【写在前面:首先,我是个菜鸡,没认真学多久的C++,被迫自学了半个小时C# winform界面设计,而且是第一次写博客。其次,这个程序里面并没用什么高端大气上档次的算法,就是一些基础,没有类(class)啊什么的,只有一些函数,有一些方法确实是很笨,但是好歹是我想出来的,自我感觉还是很好理解的,吧。代码在下面的链接里下载,不想看我叭叭的就直接下代码】
C++实现:
C#实现:
【百度云地址】(不知道为啥,我上传的东西总是自动要积分,不能免费下载)
提取码:1be1
C++运行结果:
这里我会把这里面用到的一些算法(姑且算得上算法吧)的原理和我怎么想的解释一下,如果看的话一定要看注释!!。
string* prefix(string str)
{int len = str.length(); //获取字符串的长度string s = ""; //定义变量来存储每个元素string* result = new string[len]; //定义数组来存放前缀的元素们for (int i = 0; i < len; i++) {s = s + str[i]; //每个元素都是上一个元素往后再加一个字符result[i] = s; //将元素存放进准备好的数组容器中}return result; //返回结果数组
}
int max_res_index = ((1 + len)*len) / 2; //获取总长度
string* result_son = new string[max_res_index]; //存放子串的数组
int res_index = 0; //子串数组的下标
for (int i = 0; i < len; i++) { //每次删除最前面的字符并求前缀,直到没有字符string* temp = prefix(str); //用temp存放每一次的前缀for (int j = 0; j < len - i; j++) {//对于每一个元素,都判断其是否在前缀或后缀数组中,若在,则不将它存放进子串数组中if (if_in_it(temp[j], result_pre, result_suf, len)) continue; //执行continue,不继续执行下面的所有代码,直接跳到for循环中的j++来执行result_son[res_index] = temp[j];res_index++; //每存放一个元素,下标都加一}ase(str.begin()); //删去字符串的第一个字符delete[] temp; //一定记得释放内存,因为temp是调用了函数里new出来的值
}
bool if_in_it(string temp_s, string* r1, string* r2, int len)
{for (int i = 0; i < len; i++) { //遍历两个数组r1、r2//如果该元素与两数组中任意一个元素相同,返回true,表明该元素至少在其中一个数组中if (temp_s == r1[i] || temp_s == r2[i])return true;}return false; //若遍历完成后均不返回值,则返回false,表明元素不在两数组中
}
for (int i = 0; i < res_index; i++)
{for (int j = i + 1; j < res_index; j++) {if (result_son[i] == result_son[j]) { //如果后面有元素与当前元素相同for (int k = j + 1; k < res_index; k++) {result_son[k - 1] = result_son[k]; //用j后面的元素将该元素进行覆盖}res_index--; //下标减一j--; //原来重复的位置被新的元素替代了,所以要使用同一个下标继续}}
}
string* result_pre = prefix(str); //获得前缀
cout << "X的前缀 = { ";
for (int i = 0; i < len; i++) {cout << result_pre[i] << ", "; //遍历输出
}
cout << "空串 }n"; //结尾加上空串
C#程序运行结果:
winform我也是只学了半个小时,只知道一些必要的工具的简单使用方法,我的原则是能用就行,核心代码和C++的差不多,但是“去除与前后缀相同的元素”这部分,我讲了另一种算法(我提供的C++源码里面也有)。
用Visual studio 创建一个C# WinForm(C# Windows窗体应用程序),如下图:
创建之后就有一个窗口,点击左侧的工具箱就能看到很多组件,把需要使用的东西拖进去就行了,组件使用介绍如下图:
Lable在这里用来注释,做标记用的
ListBox在这里用来以行输出显示结果
Button在这里有两个,一个用来运行程序,一个用来退出程序
TextBox在这里用来接收用户输入的字符串。
然后单击(强调单击)你拖进去的组件,你就能在红框框里看见这个组件的属性,如果没有,那就点进紫色框框“重置窗口布局”就有了,属性里面有一项叫做(Name),指的是这个控件的ID,如下图:
一般Button控件默认ID为button1,button2,TextBox控件默认ID为textBox1…以此类推,这里我改了一下,TextBox的Name改成了text_input,ListBox的Name改成了result,解析Button的Name改成了OK,退出Button的Name改成了EXIT。
首先双击退出按钮,进入该按钮的Click函数体里面,顾名思义,这个函数就是点击按钮之后要执行的函数,点击退出按钮当然是为了退出,所以在里面写上如下代码:
this.Close(); //用以关闭整个窗口
string str = text_input.Text; //获取用户在TextBox中输入的串
int len = text_input.Text.Length; //获取输入串的长度
string output_str = "串X = " + str; //‘+’是重载,用于直接连接两个string类型的数据
result.Items.Add(output_str); //把output_str的内容附加到listbox中,每次都另起一行
private void extra(ref string[] res, string[] strs, ref int max_res, int max_strs)
{ //ref用于直接引用值,改变变量的同时也修改值,我认为相当于C++中的&for (int i = 0; i < max_res; i++) { //遍历需要去除元素的数组for (int j = 0; j < max_strs; j++) { //遍历需去除元素的来源数组if (i == max_res) break; //如果遍历已经到达尾部,直接退出循环if (res[i] == strs[j]) { //判断数组res中的元素与strs中的元素是否相同for (int k = i + 1; k < max_res; k++) {res[k - 1] = res[k]; //用其后面的值将其覆盖达到删除的作用}max_res--;j = -1; //为了让j再次从0开始}}}
}
步骤 | i | j | res[i] | strs[j] | res={a,b,b,c,d} | max_res | i与j的变化情况 |
---|---|---|---|---|---|---|---|
1 | 0 | 0 | a | b | {a, b, b, c, d} | 5 | (j++)=1<2 |
2 | 0 | 1 | a | d | {a, b, b, c, d} | 5 | (j++)=2, (i++)=1<5 |
3 | 1 | 0 | b | b | {a, b, c, d, d} | 4 | j=-1, (j++)=0<2 |
4 | 1 | 0 | b | b | {a, c, d, d, d} | 3 | j=-1, (j++)=0<2 |
5 | 1 | 0 | c | b | {a, c, d, d, d} | 3 | (j++)=1<2 |
6 | 1 | 1 | c | d | {a, c, d, d, d} | 3 | (j++)=2, (i++)=2<3 |
7 | 2 | 0 | d | b | {a, c, d, d, d} | 3 | (j++)=1<2 |
8 | 2 | 1 | d | d | {a, c, d, d, d} | 2 | j=-1, (j++)=0<2, i==max_res break |
private void text_input_KeyPress(object sender, KeyPressEventArgs e)
{if (e.KeyChar == 'r') //实现按下Enter键执行按钮OK的功能OK.PerformClick();
}
//输出前缀及个数
string[] result_pre = prefix(str);
string output_pre = "X的前缀 = { "; //定义一个用来整理结果的字符串
for(int i=0;i<len;i++) {output_pre = output_pre + result_pre[i] + ", "; //把前缀元素一个一个连接在output字符串尾部
}
output_pre = output_pre + "空串 } 个数 = " + (len + 1); //最后自主加上空串,顺便输出一下个数
result.Items.Add(output_pre); //将整理好的结果加在ListBox的末尾显示
【由于本人学艺不精,C++少了释放内存的部分,一定记得加上,new和delete一定配套使用!而C#好像不用释放,具体我也不晓得】
【写在最后:程序代码在最前面的链接里面,没看到的仔细看一下。
我确实是学的不多也学的不精,这篇文章是纯原创,第一次写博客也是就像是把实验报告细化之后写了上来,有很多不足之处也希望批评改正,同时,有什么问题也可以和我讨论,毕竟这都是照着我的思路来写的,可能会有看不懂的地方。】
本文发布于:2024-01-31 07:59:41,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170665918426932.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |