2011年北理复试上机题

1.输入一组单词(区分大小写),统计首字母相同的单词个数,相同的单词不累加,输出格式“字母,以该字母为首的单词个数”。

set用法链接

注意:map本身就是按字母序排序的。以任意顺序录入char或者string,迭代器迭代时都是字母序。

#include<iostream>
#include<string>
#include<map>
#include<set>

using namespace std;

int main()
{
    set<string>s;//解决相同单词查重问题
    map<char, int>m;
    string str;
    while (cin >> str)s.insert(str);
    set<string>::iterator i;
    for (i = s.begin(); i != s.end(); i++)m[(*i)[0]]++;
    map<char, int>::iterator j;
    for (j = m.begin(); j != m.end(); j++)cout << j->first << " " << j->second << endl;
    return 0;
}

2.输入一组单词,(区分大小写),输出这些单词的字典排序。

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{
    vector<string> v;
    string s;
    while (cin >> s)v.push_back(s);
    sort(v.begin(), v.end());
    vector<string>::iterator i;
    for (i = v.begin(); i != v.end(); i++)cout << *i << " ";
    cout << endl;
    return 0;
}

3.给一个字符串(aaaa(bbb(cccc,dddd),eeee(ffff))),该字符串表明的是各个人的层次关系。如aaaa是bbb和eeee的领导,bbb是cccc和dddd的领导。现要求你输入一个名称如ffff,要求你输出其的领导关系。应输出:aaaa>eeee>ffff 。

substr用法

半小时处理链表各种情况,半小时bug在substr,我以为是写起点和终点,才发现是起点和长度。半小时解决各种小问题。一杯茶,一根烟,一个代码调一天。

#include<iostream>
#include<string>
#include<cstring>
#include<stack>
using namespace std;

int loc = 0, st = 0, i;//划分字符的起点
string s, x;
stack<string>sta;

struct P
{
    string name;
    P* leader;
}t[105];

P* create(P* l, string n)
{
    t[loc].leader = l;
    t[loc].name = n;
    return &t[loc++];
}

P* pre = NULL;

void Do(P* l)
{
    string n = s.substr(st + 1, i - st - 1);
    P* node = create(l, n);
    pre = node;//leader变成它自己
    st = i;//每次括号的位置
}

int main()
{
    cout << "请输入关系结构字符串:" << endl;
    cin >> s;
    cout << "请输入要查找的名字:" << endl;
    cin >> x;
    for (i = 1; i < s.length(); i++)
    {
        if (s[i] == '(')
        {
            if (st == i - 1)st = i;
            else if (s[st] == ',') Do(pre->leader);
            else if (s[st] == '(') Do(pre);
        }
        else if (s[i] == ',')
        {
            if (st == i - 1)//前面一定是')'
            {
                st = i;//更新括号的位置
                pre = pre->leader;//一级结束,更新领导关系
            }
            else if (s[st] == '(') Do(pre);
            else if (s[st] == ',') Do(pre->leader);
        }
        else if (s[i] == ')')
        {
            if (s[st] == '(') Do(pre);
            else if (s[st] == ',') Do(pre->leader);
            else if (st == i - 1)st = i;
        }
    }
    for (int j = 0; j < loc; j++)
    {
        if (t[j].name == x)
        {
            P* tmp = &t[j];
            while (tmp != NULL)
            {
                sta.push(tmp->name);
                tmp = tmp->leader;
            }
            string na;
            int flag = 0;
            while (!sta.empty())
            {
                na = sta.top();
                sta.pop();
                if (!flag)
                {
                    cout << na;
                    flag = 1;
                }
                else cout << ">" << na;
            }
            cout << endl;
            break;
        }
    }
    return 0;
}

 解法二:只留下涉及目标的层级元素,其他全部暴力删掉,思路清晰,赞!多学习这种整体和简化思想!

#include <iostream>
#include <string>
using namespace std;

bool ischar(char c) 
{
    if ((c >= 'a'&&c <= 'z') || (c >= 'A'&&c <= 'Z')) return true;
    else return false;
}

int main() 
{
    string s, str[100], tmp, aim;
    cin >> s;
    cin >> aim;
    int n = 0;//str中存放的字符串个数; 
    for (int i = 0; i < s.length(); i++) 
    {
        if (s[i] == '(') continue;//右括号无意义
        else if (s[i] == ','|| s[i] == ')') n--;//逗号前的元素都删掉,每个层级只留目标元素,左括号就把最低层级删掉
        else //如果是字符,则提取单词
        {
            tmp = "";//初始化
            while (ischar(s[i])) tmp += s[i++];
            str[n++] = tmp;//存入答案数组
            if (aim == tmp) break;//找到目标
            i--;//跳过整个单词,只留最后一位字符供下一次循环
        }
    }
    for (int i = 0; i < n; i++) 
    {
        if (i == 0) cout << str[i];
        else cout << ">" << str[i];
    }
    return 0;
}

 

posted @ 2019-08-18 18:07  郭怡柔  阅读(176)  评论(0)    收藏  举报