合法字符串

用n个不同的字符(编号1 - n),组成一个字符串,有如下2点要求:

1、对于编号为i的字符,如果2 * i > n,则该字符可以作为最后一个字符,但如果该字符不是作为最后一个字符的话,则该字符后面可以接任意字符;

2、对于编号为i的字符,如果2 * i <= n,则该字符不可以作为最后一个字符,且该字符后面所紧接着的下一个字符的编号一定要大于2 * i。

问:有多少长度为M且符合条件的字符串。

例如:N = 2,M = 3。则abb,bab,bbb是符合条件的字符串。剩下的均为不符合条件的字符串。


#define N 4
#define M 5

void findValidStr(char* elems, char* result, int pos) {
    if (pos == M) {
        result[M] = '\0';
        puts(result);
    } else {
        if (pos == 0) {
            int i = pos;
            for (i = pos; i < N; i++) {
                result[pos] = elems[i];
                findValidStr(elems, result, pos + 1); 
            }   
        } else {
            int i = 0;
                
            int lastI = result[pos - 1] + 1 - 'a';
                
            if (lastI * 2 <= N) {
                i = lastI;
            }   
                
            if (pos == M - 1) {
                if (i != lastI) {
                    i = N / 2;
                }else if(2*i<=N)
                {   
                    i = N / 2;
                }   
            }   
                
            for (; i < N; i++) {
                result[pos] = elems[i];
                findValidStr(elems, result, pos + 1); 
            }   
        }   
    }   
}

### 回答1: 可以使用顺序栈来实现该算法。具体步骤如下: 1. 遍历字符串str,找到@字符的位置,如果@字符不唯一,则不是合法字符串,直接返回false。 2. 将@字符之前的子串依次入栈。 3. 从@字符之后的位置开始遍历字符串str,依次将字符出栈,并与遍历到的字符比较,如果不相等,则不是合法字符串,直接返回false。 4. 如果遍历完整个字符串str,且栈为空,则是合法字符串,返回true;否则不是合法字符串,返回false。 下面是具体的代码实现: bool isValidString(string str) { int len = str.length(); int pos = -1; for (int i = 0; i < len; i++) { if (str[i] == '@') { if (pos != -1) return false; pos = i; } } if (pos == -1) return false; stack<char> s; for (int i = 0; i < pos; i++) { s.push(str[i]); } for (int i = pos + 1; i < len; i++) { if (s.empty() || s.top() != str[i]) { return false; } s.pop(); } return s.empty(); } ### 回答2: 题目分析: 本题需要设计一个算法来判断一个字符串是否为“序列1@序列2”形式的字符串,其中序列2是序列1的逆序,并且在字符串str中恰好只有一个@字符。为了解决这个问题,可以考虑如下的算法步骤: 1. 创建一个空的顺序栈stack; 2. 依次读入字符串str中的每一个字符,判断其是否为@字符; 3. 如果遇到@字符,开始进行栈的操作,讲栈中的元素依次弹出,得到序列2; 4. 将剩余的字符依次压入栈中,得到序列1; 5. 判断序列1和序列2是否相等,如果相等,说明该字符串合法字符串,否则不是。 算法实现: 下面是一个具体的算法实现: ``` bool isValid(string str) { int len = str.length(); int mid = len / 2; int i = 0; char tmp; stack<char> stack1; stack<char> stack2; for (i = 0; i < mid; i++) { stack1.push(str[i]); // 将第一半字符入栈 } if (len % 2 != 0) i++; // 如果字符串长度为奇数,跳过@字符 for (; i < len; i++) { if (stack1.empty()) return false; // 如果栈为空,说明没有字符能够和栈中的元素匹配 tmp = stack1.top(); stack1.pop(); // 弹出栈顶元素 if (str[i] != tmp) return false; // 判读当前字符和栈顶元素是否匹配 } if (!stack1.empty()) return false; // 如果栈不为空,说明字符串中的字符数量不匹配 return true; } ``` 代码解释: * str.length()用于获取字符串str的长度; * mid用于计算字符串的中间位置,将字符串分成两半; * stack1和stack2表示栈; * 将第一半的字符压入stack1中; * 将剩余的字符和stack1中的字符逐个比较,如果匹配,则弹出stack1中的元素;如果不匹配,说明该字符串不是合法字符串; * 最后,判断stack1是否为空,如果不为空,说明字符串中的字符数量不匹配,不是合法字符串。 参考链接: CSDN博客:https://blog.csdn.net/zagdonkey/article/details/82737047?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162840666516780264159498%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=162840666516780264159498&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_blog_default-5-82737047.pc_search_result_control_group&utm_term=用栈判断字符串是否为“序列1@序列2”&spm=1018.2226.3001.4187 Stack Overflow:https://stackoverflow.com/questions/40734397/check-if-given-string-is-of-form-sequence1-sequence2-in-c-using-stl-stack ### 回答3: 首先,根据题目要求,字符串str中应该恰好只有一个@字符。我们可以使用一个计数器,来记录@字符出现的次数,如果大于1或小于1则说明字符串合法。 其次,我们需要使用顺序栈来判断序列1和序列2是否为逆序关系。具体做法是,遍历字符串str,将@字符之前的字符逐个入栈,然后将@字符之后的字符逐个取出比较,如果与栈顶元素相同,则继续出栈比较,直到栈为空或不相同为止。如果栈为空,则说明序列1和序列2为逆序关系。反之,如果栈非空,则说明序列1和序列2不为逆序关系。 最后,我们需要判断整个字符串是否合法。具体做法是,判断@字符是否在第一个或最后一个位置,如果是,则字符串合法。否则,进行第二步的栈操作,根据栈是否为空判断序列1和序列2是否为逆序关系,如果不是,则字符串合法;反之,则字符串合法。 综上所述,我们可以设计如下算法来判断字符串str是否为形如“序列1@序列2”的合法字符串: 1. 初始化计数器count=0,栈stack为空。 2. 遍历字符串str,如果字符为@,则count=count+1;否则,将字符入栈stack。 3. 如果count不等于1,则输出字符串合法,结束算法。 4. 将栈stack中元素逐个取出,并与@字符之后的字符比较,如果相同,则继续取出比较,直到栈为空或不相同为止。 5. 如果栈为空,则说明序列1和序列2为逆序关系;否则,说明序列1和序列2不为逆序关系,输出字符串合法,结束算法。 6. 如果@字符在第一个或最后一个位置,则输出字符串合法,结束算法;否则,输出字符串合法,结束算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值