0

前言:教授制定的指导方针,我必须使用数组,而不是其他一些数据结构。他的伪代码(不是很简洁)我们应该遵循的方法:

name and grade are read into a temporary location
loop from the end of the filled part of the array down to beginning {
if (new last name < current last name) {
   copy current name and grade down
}
else if (new/current last names are equal and new first name < current first name) {
   copy/assign current name and grade down
}
else {
   found right place, break out of loop
}
}
now that you've made room, insert (copy) new name into correct sorted position

我看到我可能通过尝试读取数组位置 [-1] 来打破数组界限,但我想不出一种方法来避免这种情况,因为我从我拥有的项目数量倒数并且必须比较它们.

我正在从文本文件中读取行并将每行的片段存储到一个结构中。然后我使用插入排序算法按字母顺序存储结构。但是,我的数组似乎没有填充前几行,而新行只是覆盖了前几行......好像我的一个比较测试失败了,因为我的复制位置似乎从未改变,尽管这可能是因为初始数组填充以某种方式失败。我觉得很愚蠢,我一定错过了一些简单的东西......而且我的 DisplayList 模块显然从来没有得到一个填充了任何东西的数组。我是否以不正确的方式更改数组?

这是有问题的模块:

bool sortInput(ifstream &infile, StudentType students[], int size)
{
   StudentType temp;
   int copyToHere;

   if(size == 0)
   {
      infile >> temp.last >> temp.first >> temp.grade;
      strcpy(students[0].last, temp.last);
      strcpy(students[0].first, temp.first);
      students[0].grade = temp.grade;
      size++;
   } 

   while(infile)
   {
      infile >> temp.last >> temp.first >> temp.grade;
      //cout << "TEST" << temp.last << temp.first << temp.grade << endl;

      for(int i = size; i > 0; i--)
      {       
         if(strcmp(temp.last, students[i-1].last) < 0)
         {
            students[i] = students[i-1];
            students[i-1] = temp;
         }
         else if(strcmp(temp.last, students[i].last) == 0 && strcmp(temp.first, students[i].first) < 0)
         {
            students[i] = students[i-1];
         }
         else
         {
            break;
         }

         copyToHere = i;
      }

      cout << "Size = " << size << " and copy position = " << copyToHere << endl;
      students[copyToHere] = temp;
      size++;

      //test to see if array is populated properly
      for(int i = 0; i < size; i++)
      {
         cout << "Name is " << students[i].first << " " << students[i].last << " and grade is " << students[i].grade << endl;
      }

      cout << "DONE" << endl;

   } //end while loop

   return true;
}

这是完整的代码(如果有必要出于任何原因或进一步的上下文):

// ----------------------------------------------------------------------------
// You write meaningful doxygen comments and assumptions

#include <string.h>
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;

int const MAXSIZE = 100;            // maximum number of records in total
int const MAXLENGTH = 31;           // maximum string length 
int const MAXGRADE = 100;           // highest possible grade
int const LOWGRADE = 0;             // lowest possible grade
int const GROUP = 10;               // group amount
int const HISTOGRAMSIZE = (MAXGRADE-LOWGRADE)/GROUP + 1;    // grouped by GROUP

struct StudentType  {               // information of one student
   int grade;                       // the grade of the student
   char last[MAXLENGTH];            // last name (MAXLENGTH-1 at most)
   char first[MAXLENGTH];           // first name (MAXLENGTH-1 at most)
};

// prototypes go here
bool sortInput(ifstream &, StudentType [], int);
void displayList(StudentType [], int);
/*setHistrogram();
displayHistogram();
findAverage();*/

//------------------------------- main ----------------------------------------
int main()  {
   StudentType students[MAXSIZE];   // list of MAXSIZE number of students
   int size = 0;                    // total number of students
   int histogram[HISTOGRAMSIZE];    // grades grouped by GROUP
   int average = 0;                 // average exam score, truncated

   // creates file object and opens the data file
   ifstream infile("data1.txt");
   if (!infile)  { 
      cout << "File could not be opened." << endl; 
      return 1;  
   }

   // read and sort input by last then first name
   bool successfulRead = sortInput(infile, students, size);              

   // display list, histogram, and class average 
   if (successfulRead)  {
      displayList(students, size);
     // setHistogram(... you figure parameters ...);
     // displayHistogram(... you figure parameters ...);
     // average = findAverage(... you figure parameters ...);
      cout << "Average grade: " << average << endl << endl;
   }
   return 0;
}

bool sortInput(ifstream &infile, StudentType students[], int size)
{
   StudentType temp;
   int copyToHere;

   if(size == 0)
   {
      infile >> temp.last >> temp.first >> temp.grade;
      strcpy(students[0].last, temp.last);
      strcpy(students[0].first, temp.first);
      students[0].grade = temp.grade;
      size++;
   } 

   while(infile)
   {
      infile >> temp.last >> temp.first >> temp.grade;
      //cout << "TEST" << temp.last << temp.first << temp.grade << endl;

      for(int i = size; i > 0; i--)
      {       
         if(strcmp(temp.last, students[i-1].last) < 0)
         {
            students[i] = students[i-1];
            students[i-1] = temp;
         }
         else if(strcmp(temp.last, students[i].last) == 0 && strcmp(temp.first, students[i].first) < 0)
         {
            students[i] = students[i-1];
         }
         else
         {
            break;
         }

         copyToHere = i;
      }

      cout << "Size = " << size << " and copy position = " << copyToHere << endl;
      students[copyToHere] = temp;
      size++;

      //test to see if array is populated properly
      for(int i = 0; i < size; i++)
      {
         cout << "Name is " << students[i].first << " " << students[i].last << " and grade is " << students[i].grade << endl;
      }

      cout << "DONE" << endl;

   } //end while loop

   return true;
}

void displayList(StudentType students[], int size)
{
   cout << "List of names sorted:" << endl;

   for(int i = 0; i < size; i++)
   {
      cout << " " << students[i].grade << " " << students[i].last << " " << students[i].first << endl;
   }
}

// ----------------------------------------------------------------------------
// functions with meaningful doxygen comments and assumptions go here
4

2 回答 2

1

您的插入排序并没有真正正确插入。让我们看一下主插入循环的一部分:

   if(strcmp(temp.last, students[i-1].last) < 0)
     {
        students[i] = students[i-1];
        students[i-1] = temp;
     }

这样做的目的显然是temp在 position 插入数组i-1。您正在将项目i-1移至,i但数组中的其他元素发生了什么?您需要将它们全部向上移动一个位置,以便为插入的元素腾出空间。就像是:

memmove(students + i, students + i - 1, sizeof(students[0]) * size - i - 1);

您的代码中还有其他问题。copyToHere可能未初始化。您正在temp多次复制到数组中(students[i-1] = temp;并且students[copyToHere] = temp;不需要两者)。一旦你完成了内循环的插入,你应该打破。您对列表为空时的特殊处理并不是真正必要的,依此类推。

查看插入排序算法的伪代码,看看您是否可以简化和重写您的伪代码以消除问题。

于 2013-10-06T23:10:10.293 回答
0

解决我自己的问题哈哈。我因为没有正确完成 else 语句而很愚蠢。现在我正在重做我的名字比较,因为它不会按字母顺序排列相同的姓氏。

经验教训:在认为你被分叉之前把它全部记下来。现在我真的觉得自己像个白痴,希望没有浪费很多窥视时间。

  for(int i = size; i > 0; i--)
  {       
     if(strcmp(temp.last, students[i-1].last) < 0)
     {
        students[i] = students[i-1];
        students[i-1] = temp;
     }
     else if(strcmp(temp.last, students[i].last) == 0 && strcmp(temp.first, students[i].first) < 0)
     {
        students[i] = students[i-1];
        students[i-1] = temp;
     }
     else
     {
        students[i] = temp;
        break;
     }

     insertHere = i;
  }
于 2013-10-06T23:10:05.717 回答