老师告诉我说我的密码很垃圾,为什么?

时间:2019-03-26 03:59:43

标签: c

这两种算法之间有很大区别吗?

这是我的:

void MergeList(sqList la,sqList lb,sqList *lc){
  int j,k,n=0;

  for (j = la.length - 1, k = lb.length - 1; j >= 0 && k >= 0; ){
    if (*(la.elem + j) > *(lb.elem + k)){
      *(lc->elem + n) = *(la.elem + j);
      j--;
    } else if(*(la.elem + j) < *(lb.elem + k)){
      *(lc->elem + n) = *(la.elem + k);
      k--;
    } else {
      *(lc->elem + n) = *(la.elem + j);
      j--;
      k--;
    }
    n++;
    lc->length++;
  } 

  for ( ;j >= 0; j--){
    *(lc->elem + n) = *(la.elem + j);
    lc->length++;
  }

  for ( ;k >= 0; k--){
    *(lc->elem + n) = *(lb.elem + k);
    lc->length++;
  }
}

这是本书中的

void MergeList(sqList la,sqList lb,sqList *lc){
  ElemType *pa,*pb,*pc,*pa_first,*pb_first;

  pa = la.elem + la.length - 1;
  pb = lb.elem + lb.length - 1;
  pc = lc->elem;

  pa_first = la.elem;
  pb_first = lb.elem;

  while(pa >= pa_first && pb >= pb_first){
    if(*pa > *pb)
      *pc++ = *pa--;
    else if(*pa < *pb)
      *pc++ = *pb--;
    else{
      *pc++ = *pa-- = *pb--;

    }
    lc->length++;

  }

  while(pa >= pa_first)
  *pc++ = *pa--;
  while(pb >= pb_first)
  *pc++ = *pb--;
}

2 个答案:

答案 0 :(得分:1)

我的重构...

所做的更改:

  • 使MergeList返回列表,因此调用者可以执行resultList = MergeList(...之类的操作,以使所产生的影响更加明显。

  • 更改了变量名,使它们更具描述性

  • 到处都添加了“左括号前的空格”

  • 到处都添加了“逗号后的空格”

  • 在各处添加了“运算符周围的空间”

  • 使用数组查找替换了指针计算(请参见Jeremy Friesner的评论)

  • 替换了过于复杂的for()恶作剧(使用逗号,空片断),更容易/更容易读取循环

  • 添加了文档(功能开始之前)

  • 在功能中添加了注释

  • const添加到了来源列表

代码:

// Construct a new list sorted by descending order of "elem" by merging data from
// two existing lists that are already sorted by descending order of "elem".
//
// WARNINGS:
//   If both source lists are not sorted the resulting list will not be sorted.
//   Caller MUST ensure that enough memory is allocate for the resulting list before calling this function.

sqList *MergeList(const sqList list_a, const sqList list_b, sqList *result_list) {
  int j, k, n = 0;

  // Do entries from both source lists until there's nothing left in at least one of the source lists

  j = list_a.length - 1;
  k = list_b.length - 1;
  while(j >= 0 && k >= 0) {
    if (list_a.elem[j] > list_b.elem[k]) {
      result_list->elem[n] = list_a.elem[j];
      j--;
    } else if(list_a.elem[j] < list_b.elem[k]) {
      result_list->elem[n] = list_a.elem[k];
      k--;
    } else {
      result_list->elem[n] = list_a.elem[j];
      j--;
      k--;
    }
    n++;
    result_list->length++;
  } 

  // If all entries in list_a haven't been consumed, copy the remaining entries to the result list

  while(j >= 0) {
    result_list->elem[n] = list_a.elem[j];
    result_list->length++;
    j--;
  }

  // If all entries in list_b haven't been consumped, copy the remaining entries to the result list

  while (k >= 0) {
    result_list->elem[n] = list_b.elem[k];
    result_list->length++;
    k--;
  }

  return result_list;
}

答案 1 :(得分:0)

  

这两种算法之间有很大区别吗?

他们做的不一样,所以是的,有很大的不同

您的代码中有一个错误,我想这是一个经典的复制粘贴错误。这行是错误的:

} else if(*(la.elem + j) < *(lb.elem + k)){
  *(lc->elem + n) = *(la.elem + k);    // ERROR... la.elem should be lb.elem
  k--;
} else {

除了lc->length的计算不同。在本书的这段代码中:

while(pa >= pa_first)
    *pc++ = *pa--;

没有增量,但是在您的代码中

  for ( ;j >= 0; j--){
    *(lc->elem + n) = *(la.elem + j);
    lc->length++;
  }

有。所以又有一个区别。我猜这本书是错的,而你是正确的。

本书中的代码递减一个指针,并将其与指向第一个元素的指针进行比较。由于递减的指针最终将指向第一个元素之前,因此代码具有未定义的行为。

  

我的老师告诉我我的代码是垃圾,为什么?

老师不应该这样说...。而老师至少应该解释原因。

评估代码时,有几件事要重点关注:

  • 功能,即它在做什么吗?这是最高优先级

  • 性能,即代码是否以您需要的速度执行

  • 可维护性,即易于阅读,理解和维护的代码。

您的代码不易阅读,但是由于书中的代码是错误的,我仍然会更喜欢您的代码(在修正了拼写错误之后)。

您可以更改以提高可读性的一个简单示例:

*(la.elem + j) --> la.elem[j]

还要注意,这本书的代码不容易阅读。请看这本书的这一行:

*pc++ = *pa-- = *pb--;

作为代码阅读者,只能想到:“此代码应该做什么?”