函数内部的 C 问题,在另一个单词中搜索一个单词并返回位置

标签 c string

下面的 C 问题在 s2 中搜索 s1 并返回 s1 在 s2 中找到的位置。我写了这段代码,它适用于像 s1: car s2: carnal 这样的值,但如果我有 s1:car 和 s2: cbrcarnal 我认为它进入了一个无限循环或 smth 但它什么也不会显示。你们能看到吗问题?它必须在我的职能范围内。哦,我不允许使用 strstr。

代码:

#include "stdafx.h"
#include "stdio.h"
#include "string.h"

int subsir(char s1[],char s2[],int k)
{    int n,m,i=0,j,poz=-1;
n=strlen(s1);
m=strlen(s2);
if(n>m)
return -1;
j=k;
while(j<=m-n)
if((s1[i]==s2[j])&&(s1[n-1]==s2[j+n-1]))
{
    poz=j;
    while(j+1<poz+n-1)
        if(s1[i+1]==s2[j+1])
            {i++;
            j++;
            }
        else
            return subsir(s1,s2,poz++);
}
else
j++;

if(poz!=-1)
    return poz;
else
    return -1;
}

int _tmain(int argc, _TCHAR* argv[])
{char s1[30],s2[30];
int n;
printf("introduceti sirul 1: ");
scanf("%s",&s1);
printf("introduceti sirul 2: ");
scanf("%s",&s2);
n=subsir(s1,s2,0);
if(n!=-1)
    printf("%s is found in %s, at: %d\n",s1,s2,n);
else
    printf("s %s is not found in %s\n",s1,s2);

}

最佳答案

这是您的代码的格式化版本。我所做的唯一更改是注释、大括号、空格、声明变量更接近它们的使用位置、将一个 while 循环更改为 for 循环以及删除无效的后增量。它与您的代码完全相同:

int subsir(char s1[], char s2[], int k) {
    // Return location of s1 in s2, starting at index k in s2.

    int n = strlen(s1);
    int m = strlen(s2);
    if (n > m)  // s1 cannot be in s2
        return -1;

    int poz = -1;
    for (int j = k, i = 0; j <= m - n;) {
        // if first and last character in s1 match corresponding locations in s2
        if((s1[i] == s2[j]) && (s1[n - 1] == s2[j + n - 1])) {
            // save current s2 location in poz
            poz = j;
            while (j + 1 < poz + n - 1) {
                if(s1[i + 1] == s2[j + 1]) {
                    i++;
                    j++;
                }
                else {
                    return subsir(s1, s2, poz);
                }
            }
        }
        else {
            j++;
        }
    }

    return poz;
}

有了这个版本,您应该更容易发现问题:

  • 我知道您已经想到并明确地写在某个地方(或者您只是从作业描述中阅读),但它总是有助于您的思维过程包括一个简短的句子关于功能的目的。这是第一条评论。

  • 我通常不会在我的代码中包含第二条和第三条注释,但我写的对象与您不同。解释“为什么”(针对第二条评论)以及更复杂的表达式如何工作(针对第三条评论)应该对您有所帮助。

  • 第四条评论是指定 poz 服务的角色的开始。类似于简短的函数描述,您应该能够对每个变量进行简短的介绍。通常,对于变量 n、m、k、j 和 i,您不必将其显式地放入代码中 — 但如果您感到困惑,请开始添加它们。例如,“k 是要搜索的起始索引”、“n 是 s1 的长度”、“j 和 i 分别是 s2 和 s1 中的‘当前’位置”,等等。

    <
  • 我删除的后增量是在 return 语句中,但由于控制永远不会返回到此函数(因此永远不会再次使用 poz),它没有影响。

  • 您检查了 poz 是否为 -1,如果是,则返回 -1;否则返回poz。这和直接返回poz是一样的。

  • 你修改了 i,但是如果控制从那个 while 循环中逃脱,你永远不会将它重置为零;因此,您永远不会从 s1 的开头开始搜索。

  • 因为您在递归调用中从 poz(而不是 poz + 1)开始,所以您陷入了一个循环,不断地一遍又一遍地检查相同的位置。 (传递 poz + 1 可以解决这个问题。)

从这里继续,我会将您的内部循环重构为一个单独的函数,执行与 strncmp 等效的操作——或者如果可以的话,直接使用 strncmp。更大的模块化使问题更容易推理。

这里不需要递归,但以这种方式对问题进行建模很好:

  • 如果s1在s2中从位置k开始,返回k
  • else 调用 subsir(s1, s2, k + 1) 在下一个位置搜索
    • 这通常是在循环中而不是递归调用中完成的,但是通过尾调用优化,它是完全一样的

关于函数内部的 C 问题,在另一个单词中搜索一个单词并返回位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4148646/

相关文章:

c - 在 C 中修改字符串

c - 如何使用 VBO 在 OpenGL 上使用 GL_TEXTURE_2D_ARRAY

c - 试图将整个结构复制到另一个相同类型的结构......但出现错误

java - 需要帮助迭代在较大的二维数组中找到的较小的二维 "subarrays"

c - 查找文本文件中每一行的行大小

java - Java 中的字符串归并排序 - 链表

c - C 中是否存在依赖于两个不同分配的整数表示的用例?

C++:方法中的字符串成员别名

string - 如何在 Rascal 中删除字符串中的空格?

string - 将json格式时间戳转换为golangs time.Time