【问题标题】:Binary search, strcmp two dynamic arrays of strings in C二进制搜索,strcmp C中两个动态字符串数组
【发布时间】:2012-04-01 18:57:04
【问题描述】:

我对 C 编程还很陌生,但我尽我所能去理解它。我有两个从两个纯文本文件填充的动态字符串。一个是字典的形式,另一个只是用户输入。我想要得到的是对字典中每个用户输入的单词进行二进制搜索,并找出它是否存在(我猜是一种拼写检查器)。

我的二进制搜索功能卡住了:

char **dictElem;
int dictSize;
char **inputElem;

int binsearch(const char *val){
  int pos;
  int beg=0;
  int end=dictSize-1;
  int cond=0;

  while (beg<=end){
    pos=(beg+end)/2; //Jump in the middle
    if ((cond=strcmp(dictElem[pos],val)) == 0)
      return pos;
    else if (cond<0)
      beg=pos+1;
    else
      end=pos-1;
  }
  return 0;
}

dictEleminputElem 都已被其他方法读取,并且(假设)两个 [0] 元素都是相等的字符串 "aa"

但是,在我运行 binsearch(inputElem[0] 后,它总是返回 0。我只尝试了 strcmp(dictElem[0],inputElem[0]),它返回 1。

我哪里错了?是比较 char** 和 char* 吗?

统一更新: 加载dictElem的函数

void readd(FILE *file){
  int i=0,size=0; /* local size */
  char line[1024]; /* Local array for a single word read */
  printf("Loadingn dict...\n");
  while ((fgets(line,sizeof(line),file))!=NULL){
    dictElem=(char**)realloc(dictElem,(size+1)*sizeof(char *));
    dictElem[size++]=strdup(line);
  }
  printf("Total elements loaded: %d\n",size);
}

读取用户文件的功能非常相似,只是格式略有不同。

【问题讨论】:

  • 尝试在整数数组上运行您的排序函数,如果它工作正常,则转到字符串。
  • 你能告诉我们你分配dictElemval的代码吗?
  • 还有,这个算法叫“二叉搜索”,不是“二叉树搜索”,因为没有二叉树,只是一个排序好的数组。
  • 你说得对,我错了。
  • 我认为readd 正在将换行符读入dictElem 数组,所以当然将它与没有换行符的完全相同的字符串进行比较是非常愚蠢的。只是去检查一下

标签: c linux gcc binary-search strcmp


【解决方案1】:

您的代码的问题在于if ((cond=strcmp(dictElem[pos],val) == 0)) 这一行。这行代码将表达式strcmp(dictElem[pos], val) == 0 的结果赋值给变量cond,然后检查cond 是否为零。 我猜您的初衷是将strcmp 的结果存储在cond 中,因此您应该将右括号移到== 之前。正确的行是if ((cond = strcmp(dictElem[pos], val) == 0)

您的代码还有一些其他问题:

  1. 0 用作特殊的未找到值,但同时也可以是 0 在索引 0 处找到元素时返回。
  2. 使用char *val,当 最好使用const char *val,因为这个内容 字符串不会被修改。编写 const 正确的代码总是更好。

【讨论】:

  • 感谢您的回答!括号肯定有错误。但是您建议的更正行使 if 语句条件保持打开状态。尽管 Carey Gregory 似乎对 if ((cond=strcmp(dictElem[pos],val)) == 0) 这条线是正确的,但我也按照您的建议将 char 更改为常量。
  • 尽管函数仍然返回0,不管val我给它。
  • 它对我有用(尽管我手动为 dictElem 分配了值)。我想问题是你没有设置dictSize。如果没有,请检查您的字典是否已排序。
  • 因为字典文件应该是可替换的,所以我不能指定数组大小。字典肯定是排序的。 dictElem 中的 \n 字符是否重要?
  • 但是你不能在你的字典加载函数里写dictSize = size吗?在binsearch() 函数中你肯定需要dictSize。至于 newlienes,是的,它们确实很重要,您应该手动修剪它,对于某些字符串 s:s[strlen(s) - 1] = '\0'。此外,如果字典中的单词(由于某种原因)超过 1023 个字符,则需要手动连接字符串。
【解决方案2】:

你的问题是这一行:

if ((cond=strcmp(dictElem[pos],val) == 0))

括号给出了错误的评估顺序,并且 cond 将始终以 0 或 1 结尾(因为您将比较的结果 strcmp() == 0 分配给它)。试试这个:

if ((cond=strcmp(dictElem[pos],val)) == 0)

【讨论】:

    猜你喜欢
    • 2023-03-24
    • 2021-12-17
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多