在C语言中将合并两个单词合并为一个

uyhoqukh  于 2023-11-17  发布在  其他
关注(0)|答案(2)|浏览(137)

任务:从输入流中读取几行。第一行包含数字N -剩余行数(测试),N < 32。接下来的N行中的每一行包含两个由空格分隔的单词。(每个单词的长度不超过32个).每对单词都要取一个新词,使第一个的结尾与第二个的开头重合,例如,mountain + insane = mountainsane。这个单词应该输出到标准输出流。如果可以用几种方式连接单词,你应该选择提供最大公共部分的一种,例如papa + papaha = papaha(不是papapapaha)。
备注:不能使用“%c”格式逐字符输出最终字符串。必须使用“%s”格式形成并输出整个字符串。
验证码

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

int word_length(char* str)
{
  unsigned short int i;
  for (i = 0; str[i] != '\0'; i++);
  return i;
}

int main() {

  char word_1[32], word_2[32], line[64][64];
  unsigned short int n, line_number, i, j, k;

  scanf("%hu", &n);

  for(line_number = 0; line_number < n; line_number++){

    scanf("%s %s", word_1, word_2); 

    if(word_2[0] == word_1[0] && word_2[1] == word_1[1]){ 

      for(i = 0; i < word_length(word_2); i++){
      
        line[line_number][i] = word_2[i];
        
      }
    
    }
      
    else{
      
     for(j = 0; j < word_length(word_1); j++){

       if(word_2[0] != word_1[j]){
         
          line[line_number][j] = word_1[j];
         
       }

      else{ 
         
         line[line_number][j] = word_2[j];
         break;
         
      }
        
     }      

      for(k = j; k <= word_length(word_2); k++){
          
        line[line_number][k] = word_2[k - 1];
            
      }   
    }  
  }

  printf("\n");

  for(line_number = 0; line_number < n; line_number++){
    
    printf("%s\n", line[line_number]);
    
  }
  
  return 0;
  
}

字符串
基本的思路是通过第一个单词,寻找与第二个单词的第一个字母匹配的单词。如果字母不同,那么单词1的字母就被写下来,如果它们匹配,那么单词2的所有字母都被写下来。然而,我不确定这个逻辑是否正确。
| 尝试|想到|修得|
| --|--|--|
| 爸爸妈妈|帕帕马马|帕帕|
| 山地疯|芒廷桑|芒泰|
| 玩瑜伽|普拉约加|plaga|
| 木瓜|木瓜|木瓜|

e4eetjau

e4eetjau1#

关于OP代码:
1.太多的垂直空间(使用2xSP闪存)使其难以阅读。
1.重写strlen()没有明显的原因。(string.h已被包括在内。)

  1. char w1[32];(和w2)不考虑尾随NUL。
  2. char line[64][64];完全不合适。
    1.没有验证来自scanf()的返回代码。
    1.循环似乎只是对解决方案的猜测。
    没有规定所有的行都必须被缓冲后才能输出。每一行都可以/应该像它的两个字组成的那样输出。
    下面是可以工作的带注解的代码(使用编译的“字符串”,而不是从文件中阅读输入):
#include <stdio.h>
#include <string.h>

char *combine( char *dest, char *w1, const char *w2 ) {
    /* omitting checks for NULL pointers for brevity */
    /* all string buffers presumed to be of sufficient size */
    strcpy( dest, w1 ); // "word1" is always present in output

    size_t len1 = strlen( w1 ); // get both lengths
    size_t len2 = strlen( w2 );

    // determine minimum of lengths
    size_t len = len1 < len2 ? len1 : len2;

    // point into destination at that negative offset from trailing end
    // this is the point of maximum possible "overlap"
    char *cp = dest + len1 - len;

    // loop attempting to match that many characters
    while( *cp ) {
        if( strncmp( cp, w2, len ) == 0 ) {
            // matched "suffix" with "prefix"!!
            strcpy( cp, w2 ); // overlay all of "word2"
            return dest; // all done
        }
        cp++; // shorten suffix being tested
        len--; // reduce length being compared
    }

    strcat( dest, w2 ); // no commonality, so concatenate
    return dest;
}

int main(void) {
    char *tests[][3] = {
        { "papa", "mama", "papamama" }, // w1, w2 and expected result
        { "mountain", "insane", "mountainsane" },
        { "play", "yoga", "playoga" },
        { "papa", "papaha", "papaha" },

        { "", "foobar", "foobar" },
        { "foobar", "", "foobar" },

        { "foobarfoo", "bar", "foobarfoobar" },
    };
    size_t nTest = sizeof tests/sizeof tests[0];

    char dest[ 64 + 1 ]; // Account for trailing NUL

    for( size_t i = 0; i < nTest; i++ )
        printf( "'%s' + '%s'\n\t'%s'\n\t[%s]\n",
            tests[i][0], tests[i][1],
            combine( dest, tests[i][0], tests[i][1] ),
            tests[i][2] );

    return 0;
}

字符串
输出量:

'papa' + 'mama'
        'papamama'
        [papamama]
'mountain' + 'insane'
        'mountainsane'
        [mountainsane]
'play' + 'yoga'
        'playoga'
        [playoga]
'papa' + 'papaha'
        'papaha'
        [papaha]
'' + 'foobar'
        'foobar'
        [foobar]
'foobar' + ''
        'foobar'
        [foobar]
'foobarfoo' + 'bar'
        'foobarfoobar'
        [foobarfoobar]


挑战的关键是认识到并从“最大可能的重叠”开始,并从那里开始工作。

新的一天,代码调整:

函数的while()循环可以缩短以简化代码:

// while not matching remaining characters
    while( *cp && strncmp( cp, w2, len ) ) {
        cp++; // shorten suffix being tested
        len--; // reduce length being compared
    }

    strcpy( cp, w2 ); // put w2 here
    return dest;

ymdaylpp

ymdaylpp2#

我不知道它是否100%正确(我也不确定任务本身[描述太简短,没有解释很多角落案例]),也没有太多时间来检查,但它与您的测试案例一起工作。
1.请使用函数。
1.不要将简单的任务过于复杂化。

char *combine(char *w1, const char *w2)
{
    char *dest = w1;
    while(*w1)
    {
        if(*w1 && *w2) 
        {
            if(*w1 == *w2) w2++;
        }
        if(*w1) w1++;
        if(!*w1) strcpy(w1, w2);
    }
    return dest;
}

int main(void)
{
    printf("`%s`\n", combine((char[100]){"papa"}, "mama"));
    printf("`%s`\n", combine((char[100]){"mountain"}, "insane"));
    printf("`%s`\n", combine((char[100]){"play"}, "yoga"));
    printf("`%s`\n", combine((char[100]){"papa"}, "papaha"));
    printf("`%s`\n", combine((char[100]){"papa"}, ""));
    printf("`%s`\n", combine((char[100]){""}, "papaha"));
    printf("`%s`\n", combine((char[100]){""}, ""));
}

字符串
https://godbolt.org/z/xP1nsazMG
输出量:

`papamama`
`mountainsane`
`playoga`
`papaha`
`papa`
`papaha`
``

相关问题