注册 登录
编程论坛 C语言论坛

关于字符串问题,请看一下3个点为什么只过了1个

komorebi0110 发布于 2020-03-18 03:00, 2581 次点击
程序代码:
#include<stdio.h>
#include<string.h>
void print(char s[],char ss[])
{  int n=0;
   int    l=strlen(s);
     for(int i=0,j=l-1;n<l;n++)
        {
            if(s[i]<s[j]) ss[n]=s[i++];
            else if(s[i]>s[j]) ss[n]=s[j--];
            else
            {     int k;

                for(k=1;s[i+k]==s[i-k];k++);
                if(s[i+k]<s[j-k]) ss[n]=s[i++];
                else ss[n]=s[j--];


}}}
int main()
{
    int n;
    scanf("%d",&n);
    for(int p=0;p<n;p++)
    {   int l;
        char a[600];
        char b[600];
        scanf("%d\n%s",&l,a);
        printf("case #%d:\n",p);
        print(a,b);
        printf("%s\n",b);

    }
    return 0;
}
14 回复
#2
komorebi01102020-03-18 03:01
题目在https://acm.ecnu.
//虽然我也是抄了讨论区的代码但是只过了一个点不明白为什么
#3
komorebi01102020-03-18 03:03
给定长度为 N 的字符串 S,要构造一个长度为 N 的字符串 T。起初,T 是一个空串,随后反复执行下列两个操作中的任意一个,最终 目标是构造字典序尽可能小的字符串 T。
操作一:从 S 的头部取一个字符,加到 T 的尾部。
操作二:从 S 的尾部取一个字符,加到 T 的尾部。
例如:输入 N=6,S=ACDBCB;构造的 T=ABCBCD
具体按下图进行操作。
只有本站会员才能查看附件,请 登录


输入格式
第 1 行:整数 T(1≤T≤10) 为问题数。
第 2 行:第一个 问题中的 N(1≤N≤500),表示字符串 S 的长度。
第 3 行:输入一个字符串 S,只包含大小写英文字母。
第 4 ~ 2*T+1 行:后面问题的数据 ,格式与第 1 个问题相同。
输出格式

对于每个问题,输出一行问题的编号(0 开始编号,格式:case #0: 等),然后 输出由 S 字符串构造出来的 字典序尽可能小的字符串 T。
样例
Input

3
2
ba
5
SORTS
10
Sarumanarm

Output

case #0:
ab
case #1:
SORST
case #2:
Samranamru

#4
吹水佬2020-03-18 06:45
只有本站会员才能查看附件,请 登录

#include <stdio.h>
int main()
{
    char *S="ACDBCB", T[501]={0};
    int i=0, j, k, n=0;
    for (j=0; S[j]; ++j);
    --j;
    printf("%s\n", S);
    while (i<=j)
    {
        printf("%*s\n", n,T);
        k = S[i]<S[j] ? i++ : j--;
        T[n++] = S[k];
    }
    T[n] = '\0';
    printf("%s\n", T);
    return 0;
}
#5
komorebi01102020-03-18 13:04
回复 4楼 吹水佬
好像没考虑到开头=末尾的情况qaq
#6
lin51616782020-03-18 14:00
字符串结尾的 0 呢?
你的b数组
#7
komorebi01102020-03-18 14:42
回复 6楼 lin5161678
请问是什么意思?有点没明白
#8
lin51616782020-03-18 14:46
回复 7楼 komorebi0110
字符串是0结尾
你的0呢?
#9
komorebi01102020-03-18 15:23
程序代码:
#include<string.h>
void print(char s[],char ss[])
{  int n=0;
   int    l=strlen(s);
     for(int i=0,j=l-1;n<l;n++)
        {
            if(s[i]<s[j]) ss[n]=s[i++];
            else if(s[i]>s[j]) ss[n]=s[j--];
            else
            {     int k;

                for(k=1;s[i+k]==s[l-i-k-1];k++);
                if(s[i+k]<s[j-k]) ss[n]=s[i++];
                else ss[n]=s[j--];
}}



}
int main()
{
    int n;
    scanf("%d",&n);
    for(int p=0;p<n;p++)
    {   int l;
        char a[600];
        char b[600];
        scanf("%d\n%s",&l,a);
        printf("case #%d:\n",p);
        print(a,b);
      for(int count=0;count<strlen(a);count++)
        printf("%c",b[count]);
      printf("\n");

    }
    return 0;
}

//好像不是'\0'的问题耶,这样改过就对了,虽然不明白为什么直接输出b这个字符串后面会有乱码
#10
lin51616782020-03-18 15:26
回复 9楼 komorebi0110
//好像不是'\0'的问题耶,这样改过就对了,虽然不明白为什么直接输出b这个字符串后面会有乱码
这就是根正苗红的缺少结尾0 导致的错误
字符串输出 会在查找到1字节的内容是0的时候停止输出
因为结尾的地方你没有正确的写0 所以会把结尾之后字节的内容输出
加上0 就可以了
循环输出也可以
固定字节 可以不用管0
#11
komorebi01102020-03-18 15:37
回复 10楼 lin5161678
我一直以为'\0'都会自动添加的,谢谢!
但是请问为什么加了'\0'也不能直接输出字符串b呢
#12
吹水佬2020-03-18 17:10
以下是引用komorebi0110在2020-3-18 13:04:53的发言:

好像没考虑到开头=末尾的情况qaq

取头取尾结果不是一样的吗? 应该不影响下一次的选择和结果。
#13
komorebi01102020-03-18 17:22
回复 12楼 吹水佬
应该不一样吧,取头的话下一次的选择是第二个和最后一个;取尾的话下一次的选择是第一个和倒数第二个
应该要不断比较的吧?
#14
lin51616782020-03-18 17:24
回复 12楼 吹水佬
会的
比如
DBCD
必须先取开头的D
后续是 BCD取到B
最后结果是 DBCD

如果是取结尾的D
后续是 DBC 因为C小于D取到的C
最后结果是 DCBD
#15
吹水佬2020-03-18 17:35
回复 14楼 lin5161678
明白了,是我理解错,以为每次是头尾取小就可以。
这样就把 < 改为 <=
1