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

怎么在每个单词字母逆序中让标点符号的位置保持不变?

Sopphhiiaa 发布于 2020-12-24 20:26, 2681 次点击
例如:
输入
I like thinking...
输出
I ekil gnikniht...
下面是我的代码:
程序代码:
#include <stdio.h>
#include <string.h>
int main(void)
{
   
    char a[20];
    gets(a);
    int len;
    len=strlen(a);
    char b[20][20];
    int i,j,k;
    int m[20];
    j=0;
    k=0;
    for(i=0;i<len;i++)//将输入的字符串化为二维数组 每一个单词单独占一行
    {
        if(a[i]==' ')
        {
            j++;
            
            k=0;
            continue;
        }
        
        b[j][k]=a[i];
        k++;
        m[j]=k;
    }
    /*int t;
    for(t=0;t<j+1;t++)
    printf("%d\n",m[t]);
*/
   
    int p,q;
    char c[20][20];
    char d[20];
    for(p=0;p<j+1;p++)//
    {    for(q=0;q<m[p];q++)//
        {
        
            if(b[p][m[p]-1-q]>='a'&&b[p][m[p]-1-q]<='z'||b[p][m[p]-1-q]>='A'&&b[p][m[p]-1-q]<='Z')
            c[p][q]=b[p][m[p]-1-q];//逆序,c为逆序后的数组
            
        }
    }
         p=0;
         while(p<j+1)
          {
            for(q=0;q<m[p];q++)
           {
           printf("%c",c[p][q]);
           }
           p++;
           printf(" ");
          }
   
   
    return 0;
   
   
}

然后我的输出结果是这样的:
i like thinking...
i ekil    gnikniht
可以看到,标点符号没有输出且占了位置。请教大佬们我该如何修改才能显示出样例中输出的结果。
17 回复
#2
do8do8do82020-12-24 21:11

            if(b[p][m[p]-1-q]>='a'&&b[p][m[p]-1-q]<='z'||b[p][m[p]-1-q]>='A'&&b[p][m[p]-1-q]<='Z')
          点号没有被逆序。而竟然输出空格而不是乱码,我感到诧异。
#3
Sopphhiiaa2020-12-24 21:29
回复 2楼 do8do8do8
那应该是怎么改才能正确输出呀
#4
do8do8do82020-12-24 21:38
增加个else  处理非字母的字符   直接把非字母的字符写在后面
#5
do8do8do82020-12-24 21:47
每遇到一位非字母字符,整个数组的元素位置前移一位后,把非字符字符覆盖最后一个位置
#6
do8do8do82020-12-24 21:59
else {
for(j=0;j<m[p]-1; j++)
     c[p][j]=c[p][j+1];
c[p][j]=b[p][m[p]-1-q];
#7
apull2020-12-24 22:57
程序代码:

#include <stdio.h>
#include <ctype.h>

void restr(char *start, char *end)
{
    char c, *p, *q;
    p = start;
    q = end;

    unsigned int half;
    half = (q - p) / 2;

    while (p <= start + half)
    {
        c = *p;
        *p = *q;
        *q = c;

        p++;
        q--;
    }
}

int main(void)
{

    char a[20], *p, *start, *end;
    int b = 0;

    gets(a);
    p = start = end = a;

    while (*p)
    {
        if (isspace(*p) || ispunct(*p) ||*(p + 1) == '\0')
        {            
            if(b && *(p + 1) == '\0')
                end++;
            if(b)
                restr(start, end);
            b = 0;
        }
        else
        {
            if (b == 0)
                start = p;
            end = p;
            b = 1;
        }
        p++;
    }

    printf("%s\n", a);
    return 0;
}


[此贴子已经被作者于2020-12-24 23:58编辑过]

#8
Sopphhiiaa2020-12-24 23:02
我在原来的代码中这么加
程序代码:
if(b[p][m[p]-1-q]>='a'&&b[p][m[p]-1-q]<='z'||b[p][m[p]-1-q]>='A'&&b[p][m[p]-1-q]<='Z')
            c[p][q]=b[p][m[p]-1-q];//逆序,c为逆序后的数组
            else {
               
                c[p][q]=c[p][q+1];
                c[p][q]=b[p][m[p]-1-q];
                }
               

然后输出的结果是
i like thinking...
i ekil ...gnikniht
              
#9
Sopphhiiaa2020-12-24 23:11
回复 7楼 apull
谢谢你的解答,但是标点符号的位置不能改变,您的代码运行出来的结果标点符号仍然被逆序了
#10
do8do8do82020-12-24 23:13
回复 8楼 Sopphhiiaa
用我的那个试试,我不是写了几行代码吗,反正我没编译,手机打的
#11
apull2020-12-24 23:46
回复 9楼 Sopphhiiaa
疏忽了,代码修改过了,你看一下

主循环还可以写成这种方式
程序代码:

while (*p)
    {
        if (isspace(*p) || ispunct(*p))
        {            
            b = 0;
        }
        else if(isalnum(*p))
        {
            if (b == 0)
                start = p;
            if(isspace(*(p + 1)) || ispunct(*(p + 1)) ||*(p + 1) == '\0')
            {
                end = p;
                restr(start, end);
            }
            b = 1;
        }
        p++;
    }



[此贴子已经被作者于2020-12-24 23:57编辑过]

#12
Sopphhiiaa2020-12-25 00:07
回复 11楼 apull
您刚才的代码还是有一点小问题
比如我随便输入以下例子
ashk; ;wjs' wsl/
khsa; ;sjw' /lsw 这里标点符号就换了

dskh;; ajl' ,sj'//sj ;sdk'
hksd;; lja' ,js'//j 这里到后面就没有了

虽然我还不太看得懂您写的代码,但是您最后写的新的循环主体运行结果是正确的,感谢!
祝您圣诞节快乐!

[此贴子已经被作者于2020-12-25 00:15编辑过]

#13
do8do8do82020-12-25 09:31
回复 12楼 Sopphhiiaa
哈哈,是我看错了,以为你是从数组头开始读的。所以算法就写错。现我贴出代码,请你参考。
我的设计的原理是,先算出非字母的字符数,然后进行数组移位,经过调试,结果是对的
因为你的数组是20个字符,而且非字母字符也不管是否是逆序,哈,所以结果有图
#include <stdio.h>
#include <string.h>
int main(void)
{
   
    char a[20];

    int len;
    int p,q;
    char c[20][20];
    char d[20];
    char b[20][20];
    int i,j,k;
    int m[20];
    int aa=0;/*计算非字母字符的数量*/
    char temp;/*数组移位的临时存储变量*/
    j=0;
    k=0;
    gets(a);
    len=strlen(a);
    for(i=0;i<len;i++)
    {
        if(a[i]==' ')
        {
            j++;
            
            k=0;
            continue;
        }
        
        b[j][k]=a[i];
        k++;
        m[j]=k;
    }
    /*int t;
    for(t=0;t<j+1;t++)
    printf("%d\n",m[t]);*/
   

    for(p=0;p<j+1;p++)
    {      aa=0;/*初始化为零,因为每一个字符串都可能存在非字母字符*/

        for(q=0;q<m[p];q++)
        {
                c[p][q]=b[p][m[p]-1-q];/*先不管字母或非字母,都按逆序存储*/
        
            if(b[p][m[p]-1-q]>='a'&&b[p][m[p]-1-q]<='z'||b[p][m[p]-1-q]>='A'&&b[p][m[p]-1-q]<='Z') ;
            else
              aa++;/*这里是计算非字母字符数*/



            
        }
        if(aa>0)/*如果存在非字母字符则进行数组移位,每移动一次最终把头接到尾*/
        {
           for(q=0;q<aa;q++)
           {         temp=c[p][0];
                 for(j=0;j<m[p]-1;j++)
                  {
                     c[p][j]=c[p][j+1];
                  }
                  c[p][j]=temp;

                }
          }


    }
         p=0;
         while(p<j+1)
          {
            for(q=0;q<m[p];q++)
           {
           printf("%c",c[p][q]);
           }
           p++;
           printf(" ");
          }
   
      getch();/*这个你可以删除,这是wintc里加的调试函数*/
    return 0;
   
   
}
只有本站会员才能查看附件,请 登录
只有本站会员才能查看附件,请 登录
#14
rjsp2020-12-25 10:39
这题目限定了输入字符串的最大长度了吗?否则main函数没法写,我定义char a[20],你可能输入21个字符;我定义char a[2000000000000000000],你可能输入2000000000000000001个字符,……
字母逆序标点不变,那数字等其它字符呢?这样,我把判断字母/标点的函数独立出来,你可以按需修改

程序代码:
#include <stdio.h>

inline int is_alpha( int ch )
{
    return (ch>='A'&&ch<='Z') || (ch>='a'&&ch<='z');
}
inline int is_punct( int ch )
{
    return ch!=0 && !is_alpha(ch);
}

char* foo( char* s )
{
    for( char *a,*b=s; *b; )
    {
        for( a=b; is_punct(*a); ++a );
        for( b=a; is_alpha(*b); ++b );
        for( size_t i=0; a+2*i+1<b; ++i )
        {
            char t = *(a+i);
            *(a+i) = *(b-i-1);
            *(b-i-1) = t;
        }
    }
    return s;
}

int main( void )
{
#define TEST(a) {char s[]=a; puts(s), foo(s), puts(s), putchar('\n');}
    TEST( "I like thinking..." );
    TEST( "ashk; ;wjs' wsl/" );
    TEST( "dskh;; ajl' ,sj'//sj ;sdk'" );
    TEST( "   a ab abc   " );
    TEST( "a ab abc" );
#undef TEST
}
#15
do8do8do82020-12-25 11:59
要讲武德
只有本站会员才能查看附件,请 登录

#include <stdio.h>
#include <string.h>

int isa(char ch)
{
  if( (ch>='A'&&ch<='Z') || (ch>='a'&&ch<='z'))
  return 1;
  else
  return 0;
}
int main(void)
{
   
   char str[100];
   char a[100];
   int i=0,j=0,len=0;
   int k=0,c=0,d=0;
   char temp;
   gets(a);
   len=strlen(a);

   for(i=0;i<len;i++)
    {

      str[i]=a[i];
      if(isa(a[i])==1)
      {
         k++;
      }
      if( (isa(a[i+1])==0)&&k>0  )
      {      c=i;
             d=k;

        for( j=0;j<(k/2);j++)
          {  temp=str[c];
             str[c]=str[c-d+1] ;
             str[c-d+1]=temp;
             c--;
             d=d-2;
           }
           k=0;
      }
    }
     for(i=0;i<len;i++)
    printf("%c",str[i]);
    getch();
   }
#16
Sopphhiiaa2020-12-25 14:31
回复 13楼 do8do8do8
很奇怪 我运行这个程序根本没有输出结果
#17
Sopphhiiaa2020-12-25 14:31
回复 14楼 rjsp
好的,感谢!
祝您圣诞节愉快!
#18
Sopphhiiaa2020-12-25 14:39
回复 15楼 do8do8do8
你这个代码运行出来是对的 不过我还需要自己再理解一下
谢谢你抽出时间为我解答问题,祝您圣诞节快乐!
1