malloc-Problem E: 动态的字符串排序

本文详细介绍了如何使用动态分配内存和字符指针数组实现大规模字符串集合的ASCII码序排序,通过示例代码展示了完整的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem E: 动态的字符串排序
Time Limit: 5 Sec Memory Limit: 128 MB
Submit: 7723 Solved: 2128
[Submit][Status][Web Board]
Description
把字符串按照ASCII码序的从小到大排列出来。
串的ASCII码序遵循如下递归定义:
1 两串的前n-1个字符相同,第n个字符ASCII码序小的排在前面;
2 只有两串的字符完全相同时,才有两串相等。
字符的ASCII码序比较可以用strcmp()函数完成。

Input
第一行输入为一个整数N(N<=50,000),后接N行,每行一个字符串,串长不超过100,000。
Output
输出为N行,按照字符串的ASCII码序排列,ASCII码序小的排前面。
Sample Input
10
abc
bc
aca
ca
c
aac
aba
bc
da
ba
Sample Output
aac
aba
abc
aca
ba
bc
bc
c
ca
da
HINT

用二维数组很难一次性分配出这么大的空间了,要用到根据输入变化的动态分配的内存才行。这里需要动态的数据结构,比如,字符指针的数组“char *s[]”,或者是二维的字符指针“char **s”,等等。

Append Code

"动态字符串的排序”
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char a[100000];
int main()
{
    int n,i,j,len;
    char *t;
    scanf("%d",&n);
    char *p[n+1];
    getchar();
    for(i=0;i<n;i++)
    {
        gets(a);
        len=strlen(a);
        p[i]=(char*)malloc(sizeof(char)*(len+1));
        strcpy(p[i],a);
        memset(a,0,sizeof a);
    }
    for(i=0;i<n;i++)
        for(j=0;j<n-i-1;j++)
        {
           if(strcmp(p[j],p[j+1])>0)
           {
               t=p[j];
               p[j]=p[j+1];
               p[j+1]=t;
           }
        }
    for(i=0;i<n;i++)
        puts(p[i]);
    for(i=0;i<n;i++)
        free(p[i]);
    return 0;
}

operators = ['!','&', '|', '*', '+'] # 按照优先级从高到低的顺序 def postfix(elements): global operators stack = list() output = list() for ele in elements: if ele not in operators and ele not in ('(',')'): # output.append(ele) # '(' 在运算符中优先级最小,其唯一出栈条件时遇到右括号 elif ele == '(': stack.append(ele) # 若是 ) ,则出栈直到遇到 ( ,这里注意: ) 遇到的第一个 ( 一定是匹配的一对 elif ele == ')': val = stack.pop() while val !='(': output.append(val) if stack: val = stack.pop() else: break elif ele in ('&', '|', '*', '+', '!'): # 遇到运算符,比较优先级 if len(stack) == 0: stack.append(ele) continue # 比较该运算符与栈顶运算符的优先级,遇到比该运算符优先级大于或等于的则将其弹出,最后将该运算符压栈 while (ele == '!' and stack[-1] =='!') or \ (ele == '&' and stack[-1] in ('!', '&')) or \ (ele == '|' and stack[-1] in ('!', '&', '|')) or \ (ele == '*' and stack[-1] in ('!', '&', '|', '*')) or \ (ele == '+' and stack[-1] in ('!', '&', '|', '*', '+')): val = stack.pop() output.append(val) if not stack: break stack.append(ele) while stack: # 当表达式完全处理完之后,把栈中的运算符一一出栈,FILO,转化成后缀表表达式 output.append(stack.pop()) return ''.join(output) def logicalOp(tmp): idx = 0 # 当前命题元素的位置 while len(tmp) > 1: # 当最后命题仅为真值后,退出循环 if tmp[idx] in operators: if tmp[idx] == '!': # 非 # 这里把命题变元进行转换,根据后缀表达式,一定满足idx的前1位或前2位是真值而不是运算符 tmp[idx - 1] = 1 if int(tmp[idx - 1]) == 0 else 0 tmp[idx:idx + 1] = [] # 子命题结果对原命题覆盖 # 每次从头开始对命题处理 idx = 0 continue elif tmp[idx] == '&': # 合取 tmp[idx] = 1 if int(tmp[idx - 1]) == 1 and int(tmp[idx - 2]) == 1 else 0 tmp[idx - 2:idx] = [] idx = 0 continue elif tmp[idx] == '|': # 析取 tmp[idx] = 0 if int(tmp[idx - 1]) == 0 and int(tmp[idx - 2]) == 0 else 1 tmp[idx - 2:idx] = [] idx = 0 continue elif tmp[idx] == '*': # 则 tmp[idx] = 0 if int(tmp[idx - 2]) == 1 and int(tmp[idx - 1]) == 0 else 1 tmp[idx - 2:idx] = [] idx = 0 continue elif tmp[idx] == '+': # 当且仅当 tmp[idx] = 1 if int(tmp[idx - 2]) == int(tmp[idx - 1]) else 0 tmp[idx - 2:idx] = [] idx = 0 continue idx += 1 print(tmp[0]) def e(idx): global expr if idx == len(enum): # 递归终止条件为枚举完全部的变元 print('\t'.join(list(enum.values())),end='\t') # 打印出枚举情况 tmp = ' '.join(expr) # tmp为对命题处理带入真值的中间量 for ele in expr: if ele in enum: tmp = tmp.replace(ele, enum[ele]) tmp = tmp.split(' ') # 转化成list,由于字符串内部不能修改 logicalOp(tmp) return enum[var[idx]] = '0' # 枚举False,最后在转换为int类型,使得可使用字符串替换,把0,1代入 e(idx+1) # 接着对下一位变元枚举 enum[var[idx]] = '1' # 枚举True e(idx+1) if __name__=='__main__': """ Attention : 定义: !:非 (单命题变元) &:合取 |:析取 *:单条件(则) +:双条件(当且仅当) """ print('please input the problem\tExample: (p*q)&!r p&q|r*q&!s|r') inp = input('>>>') expr = postfix(inp) # expr为生成的后缀表达式 var = list() # var为命题变元 for item in expr: # 找出变元且不能重复 if item not in operators and \ item not in var and \ item not in ('(', ')'): var.append(item) # 对变元枚举TF字典 enum = {}.fromkeys(var) # 打印表头 print('\t'.join(var),end='\t') print(inp) # 从第一个变元枚举 e(0) 将以上代码转化为C语言代码
05-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值