(1):Daily[]数组多写了一个位置,但是只有162个位置,导致访问的内存越界。
解决方法:数组是从0开始计数的,有几个数据下标就写几,比如说有162个数据,那么数组最大开到[162]!记住了!这是可以进步的地方!
(2)为什么我的二叉树的ASL和别人的不一样???
解决方法:不同顺序创建出的排序二叉树是不一样的!!折磨我两个小时!!基础不牢,地动山摇!!
(3)KMP那里next数组怎么也不能赋值。
解决方法:和链表的next重复了。换一个就好了。
(4)字符串直接比大小不对。
解决方法:如果字符串是数字的话此法失效!只能用于字母之间!!!不然会有”9.99”>”10.1”的情况出现!!之前”123”,”23”那个比大小是把两个加起来,保证长度一致,在这个题里不适用!
(5)变量之间用的是中文逗号隔开,怪不得有错。
(6)一级行业的英文自己定义的fir,用的时候写business,写的时候回去看一眼。
(7)链表的遍历,p=lk->next后只能遍历一次,这不是for(int i=0;)p不是临时变量,遍历一次就到NULL了,不能下次接着使。
(8)float可以存到double里,但不能反过来。细节,不注意就会程序崩溃,不报错的那种。
(9)邻接矩阵里不相邻的两个节点的距离(二维数组中的值)路程长度不能初始化为0,不然弗洛伊德算法会认为0是最小的路程,就等于0了。
(10)保存csv文件的时候如果选csv(UTF-8编码)就是乱码,但是下面的格式还有一个是普普通通简简单单的csv!用那个就行了!!文件出现乱码先看是不是文件的问题,很有可能你是对的,我永远相信自己。
(11)功能相似的函数即使只有一点区别也要记得改名,名字不改跳到别的函数里去了。
(12)如果不让用STL的话用数组,可以用arr[k++]来模拟数组的顺序赋值。
文件相关:
(13)数组改为162之后还是内存访问越界,排查不出来错误。
解决方法:打开所对应的txt文件,看一看是不是文件本身的问题😅有的文件只有100个数据。这个情况是有大量数据(200支股票,每个股票100+个日期数据),那么以后做题遇到了一律采用vector来记录,vector的push_back()函数很好用,不用担心数组开得太大导致万一有文件没那么多数据而访问越界,或太小而不够存数据的情况发生。谢谢你,数据结构,我更加认识到STL有多么好。
(14)用读txt的方法打开csv,xlsx文件不行。
解决方法:具体问题具体分析,这俩方法不能混用。记得及时整理这个课设中用到的一些文件打开方法!读文件相关代码:(csv和txt都能用!可以说是一种“放之四海而皆准”的方法了!)
//————————————————————读文件————————————————————
ifstream ifs; //创建流对象
ifs.open("A股公司简介.csv", ios::in); //打开文件
if (!ifs.is_open()) //判断文件是否打开
{
cout << "csv文件打开失败\_(ツ)_/\n" << endl;
return;
}
string line;//临时存储文件中的一行数据
int flag = 0;
while (getline(ifs, line)) //利用 getline()读取文件中的每一行
{
stringstream ss(line);//把line里的文件放到ss里
string sub;
//一次性读一行的写法:
//while (getline(ss, sub, '\n'))
if (flag)
{
LinkList temp = new LNode;
getline(ss, sub, ',');
temp->data.code = sub;//表示把csv文件的一小个单元格的东西读到sub
/*———————读当前企业对应的txt文件,并存数据到UpDown数组中——————*/
string text = sub + ".txt";
ifstream ifsTXT; //创建流对象
string lineTXT; //临时存储文件中的一行数据
ifsTXT.open(text,ios::in); //打开文件:改错(不会嘛)
if (!ifsTXT.is_open()) //判断文件是否打开
{
cout << "txt文件打开失败\_(ツ)_/\n" << endl;
return;
}
int i = -1, flagTXT = 0;//如果不想读文件的前几行,就用flag来控制
while (getline(ifsTXT, lineTXT, '\n'))
{
stringstream ssTXT(lineTXT);
string subTXT;//临时存储一个数据项
double ssubTXT;
if (flagTXT)
{
getline(ssTXT, subTXT, ' ');
ssubTXT = stof(subTXT);//改错:string 转 double
/*这里要注意就是getline的参数类型不能变,只能是string,如果想获得数值格式,那就要自己手动用stoi,stof转换一下*/
temp->data.daily[i].oprice = ssubTXT;
/*…… …… ……*/
}
flagTXT++;
i++;
}
ifsTXT.close();//文件使用完了别忘关上,养成好习惯!
/*—————————————txt文件读取完毕———————————*/
for (int i = 0; i < 7; i++)
getline(ss, sub, ',');
//如果不想读文件的某几个单元格,可以通过这样的方式控制跳过!
/*------------------------ - 读csv文件的一行完毕-------------------- - */
内存相关;
(15)警告C6262:函数使用了堆栈的“23600”个字节: 超过了 /analyze:stacksize '16384'。。此分配针对的是编译器为“struct Stock”(第 1754 行)生成的临时项。 请考虑将某些数据移到堆中,同时也有可能报错程序崩溃访问了0xCCCCCCCD,而该内存为只读。
解决方法:主函数里只放Welcome()函数吧,其他大的量放在全局,最好不要放在任何一个函数里。而且全局变量每个函数都可以随时调用,非常方便!
编程规范性和容错性相关:
(16)一开始写了Queue,长时间没用就删了,后面发现BFS又要用,又得重写,费时费力。
解决方法:答辩通过之前不要删任何代码!!先通过再追求卓越!!
(17)有200*162次循环(数组),或者是有200个数据的大链表,但是崩溃只出现在其中的未知位置,根本不可能通过调试循环找出错误,这个时候该怎么调试呢?
解决方法:先在崩溃的位置打断点,看那个循环的i、j(或其他控制循环次数的点)分别是几,记录下它们,然后再在那个位置写类似
if (j == 154)
int c = 0;
这样的代码,再把断点打到这里,再次调试,看看自动窗口和监视窗口的变量哪里有问题,就轻松多了~这两句代码就是为了迫使程序在有问题的地方停止。数组比较好用,链表的话也可以,手动设置一个计数器就可以了,比如
int i = 0;
while (p)
{
/*…… 其他代码 ……*/
if (i == 150)
int c = 0;
p = p->next;
i++;
}
(18)代码没必要的重复片段太多。
一开始的用户菜单界面单独写在一个函数里,里面就不要再实现其他的选择分支跳转功能了,因为你每次从别的功能return到主函数,考虑到用户记不住功能,就要把菜单再次输出,那每次都写几十行菜单太占地方了,应该直接写到一个函数里,把它放最上面,每次执行完一个功能后调用一下。比如叫CaptainOnBridge(),就挺好。
(19)二叉树重建了。
在文档需求不明确的情况下,不要自己想怎么来就怎么来,先问,如果问不出来,就看大多数人是怎么做的,不要一意孤行!!!
(20)数组不想弄太大又不知道大小:可以先调试,看num,这是一个小技巧😉
(21)定义了全局变量别忘了删除函数里同名的局部变量。