大三上算法习题
创始人
2024-04-27 18:03:50
0

难度:1

1 二分查找返回关键值key在长度为len的数组arr[]中的位置,没有key则返回-1

int bi_search( int key, int arr[], int len )

//1 二分查找返回关键值key在长度为len的数组arr[]中的位置,没有key则返回-1#include 
using namespace std;int binSearch(int arr[], int len, int key)
{int low = 0;int high = len - 1;int mid;while(low <= high){mid = (low+high)/2;if(key == arr[mid]) return arr[mid];else if(arr[mid]>key) high=mid-1;else low=mid+1;}return -1;
}int main(){int arr[] = {1,2,3,4,5,6,7,8,9,10,11};int key = 0;printf("输入你要查找的数:\n");scanf("%d",&key);printf("查找的数 %d 在数组中的位置为:%d\n",key,binSearch(arr,sizeof(arr)/sizeof(arr[0]),key));return 0;
} 

执行效果:
在这里插入图片描述

2 实现指定整数的三种查询方法:

int linear_search( int arr[], int len, int key )

#include using namespace std;int better_search(int arr[],int len,int key){int i;for(i=len-1;i>=0;i--){if (arr[i]==key) {break;}} return i;
}int main(){int n=10;int arr[11]={0};printf("输入长度为10 的数组:\n");for(int i=0;iscanf("%d",&arr[i]);} int key;printf("输入要查找的数:\n");scanf("%d",&key);printf("要查找的数的位置为:%d",better_search(arr,sizeof(arr)/sizeof(arr[0]),key));return 0;
}

执行结果:
在这里插入图片描述
int better_search( int arr[], int len, int key )

#include using namespace std;int linear_search(int arr[],int len,int key){for(int i=0;iif (arr[i]==key) {return i;}} return -1;
}int main(){int n=10;int arr[11]={0};printf("输入长度为10 的数组:\n");for(int i=0;iscanf("%d",&arr[i]);} int key;printf("输入要查找的数:\n");scanf("%d",&key);printf("要查找的数的位置为:%d",linear_search(arr,sizeof(arr)/sizeof(arr[0]),key));return 0;
}

执行结果:
在这里插入图片描述
int sentinel_linear_search( int arr[], int len, int key )

#include 
using namespace std;int search(int arr[ ], int n, int k) 
{   int i = n; arr[0] = k; //0位置空出来while (arr[i] != k)//要么在1--n处找到,要么在0处出while循环i--;return i;
}int main(){int n=10;int arr[11]={0};printf("输入长度为10 的数组:\n");for(int i=0;iscanf("%d",&arr[i]);} int key;printf("输入要查找的数:\n");scanf("%d",&key);printf("要查找的数的位置为:%d",search(arr,sizeof(arr)/sizeof(arr[0]),key));return 0;
}

执行结果:
在这里插入图片描述

3 用递归的方法求解斐波那契数列第n项的值:

long fib( int n ) // 返回斐波那契数列第n项的值

#include 
using namespace std;int f(int n){if(n==1||n==2) return 1;else{return f(n-1)+f(n-2);}
}
int main(){printf("请输入要求第几个斐波那契数:\n");int n;scanf("%d",&n);printf("第%d个斐波那契数的值为:%d",n,f(n));return 0; 
}

执行结果:
在这里插入图片描述

4 数组反转,给定长度为len的数组arr[],请将里面的元素反转,

如开始为{1,5,6,2,6,7,8} 反转后为{8,7,6,2,6,5,1}
void reverse( int arr[], int len )

int reverse(int arr[]){int temp = 0;int n = arr.size();for(int i = 0; i< n/2; i++){temp = arr[n-i-1];arr[n-i-1] = arr[i];arr[i] = temp;}return arr;
}

5 给定一个字符串,若里面含有相同的字母则返回1,否则返回0.

#include using namespace std;int hashtable[1000];
int check(string a,int len){for(int i=0;iif(hashtable[a[i]]!=0) return 1;hashtable[a[i]]=1;}return 0;
}int main(){string a;getline(cin,a);int len=a.length();printf("%d",check(a,len));
}

难度:2

1 递归实现:二分查找返回关键值key在长度为len的数组arr[]中的位置,没有key则返回-1 int rec_bi_search( int key, int arr[], int low, int high )

#include 
using namespace std;int binSearch(int arr[], int len, int key)
{int low = 0;int high = len - 1;int mid;while(low <= high){mid = (low+high)/2;if(key == arr[mid]) return arr[mid];else if(arr[mid]>key) high=mid-1;else low=mid+1;}return -1;
}int main(){int arr[] = {1,2,3,4,5,6,7,8,9,10,11};int key = 0;printf("输入你要查找的数:\n");scanf("%d",&key);printf("查找的数 %d 在数组中的位置为:%d\n",key,binSearch(arr,sizeof(arr)/sizeof(arr[0]),key));return 0;
} 

2 用优化递归方法,求解斐波那契数列第n项的值: long fib( int n, long result[], int len ) 返回斐波那契数列第n项的值,,result[i]存储第i项的值,len是result的长度。

动态规划法:把每一个计算出来的数据,用一个数组保存,需要最终值时直接从数组中取即可,避免重复计算。有一个for循环,其时间复杂度为O(n),开辟一个长度为n的数组,所以空间复杂度也为O(n)

1 public int fib(int n) {
2     int[] fib = new int[n];
3     fib[0] = 1;
4     fib[1] = 1;
5     for (int i = 2; i < n; i++) {
6         fib[i] = fib[i - 2] + fib[i - 1];
7     }
8     return fib[n - 1];
9 }

3 用选择排序的方法实现对整型数据由小到大进行排序 void select_sort( int arr[], int len ) arr为数组名,len为数组的长度。

#include using namespace std;void selectionSort(int arr[], int n) {for (int i = 0; i < n; i++) {// 寻找[i, n)区间里的最小值int minIndex = i;for (int j = i + 1; j < n; j++)if (arr[j] < arr[minIndex])minIndex = j;swap(arr[i], arr[minIndex]);}}void swap(int arr[], int i, int j) {int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;
}int main(){int arr[10] = {3,5,4,2,7,23,56,6,51,76};selectionSort(arr,10);for(int i=0;i<10;i++){printf("%d ",arr[i]);}
}

4 用插入排序的方法实现对整型数据由小到大进行排序 void insert_sort( int arr[], int len ) arr为数组名,len为数组的长度。

#include
using namespace std;
int main() {int a[6] = { 2, 6, 5, 3, 4, 1};int temp, i, j;int n = 6;for (i = 1; i < 6; i++) {  // 数组的下标是从0开始的// 这里从第二个数开始枚举  即假定第一个数是有序的temp = a[i]; j = i;     // 这里temp 临时储存每一次需要排序的数while (j >= 1 && temp < a[j - 1]) {a[j] = a[j - 1];j--;}a[j] = temp;}for (i = 0; i < 6; i++) {cout << a[i] << " ";}cout << endl;return 0;
}

难度:3

1 判断字符串中的括号是否正确匹配,如正确的匹配()、()[]{}、{[]}、{([])}、错误的匹配{)、{[)}等等 正确返回1,错误返回0

#include 
#include 
#include using namespace std;int main()
{stacka;int flag=1,i;char ch[100];cin>>ch;for(i=0;iif(ch[i]=='{'||ch[i]=='('||ch[i]=='[')a.push(ch[i]);else{if(a.empty()==true){flag=0;break;}else if((ch[i]=='}'&&a.top()=='{')||(ch[i]==')'&&a.top()=='(')||(ch[i]==']'&&a.top()=='['))a.pop();else{flag = 0;break;}}}if(flag==0)cout<<"no";elsecout<<"yes";
}

2 用快速排序的方法实现对整型数据由小到大进行排序 void quick_sort( int arr[], int len )

//快速排序
#include  
using namespace std;
void QuickSort(int *array,int low,int high){	//快排 if(low>=high){	//若待排序序列只有一个元素,返回空 return ;}int i=low;	//i作为指针从左向右扫描 int j=high;	//j作为指针从右向左扫描int key=array[low];//第一个数作为基准数 while(iwhile(array[j]>=key&&i	//从右边找小于基准数的元素 (此处由于j值可能会变,所以仍需判断i是否小于j) j--;	//找不到则j减一 }array[i]=array[j];	//找到则赋值 while(array[i]<=key&&i	//从左边找大于基准数的元素 i++;	//找不到则i加一 }array[j]=array[i];	//找到则赋值 }array[i]=key;	//当i和j相遇,将基准元素赋值到指针i处 QuickSort(array,low,i-1);	//i左边的序列继续递归调用快排 QuickSort(array,i+1,high);	//i右边的序列继续递归调用快排 
}
int main(){int array[]={49,38,65,97,76,13,27,49};int length=sizeof(array)/sizeof(*array);cout<<"原始序列:";for(int i=0;icout<cout<

3 给定长度为len的数组arr,打印出数组元素的所有排序。 如arr[4]={3,5,2,7},则输出这4个整数的24种排列形式

#include
using namespace std;
//交换
void swap(int &a , int &b)
{int temp;temp = a;a = b;b = temp;} //全排列递归算法
void Perm(int list[] , int k ,int m) 
{//list 数组存放排列的数,K表示层 代表第几个数,m表示数组的长度if(k==m){//K==m 表示到达最后一个数,不能再交换,最终的排列的数需要输出;for(int i=0 ;i<=m ;i++)cout<for(int i=k;i<=m;i++){swap(list[i],list[k]);Perm(list,k+1,m);swap(list[i] , list[k]);}}}
int main(void)
{int a[]={1,2,3};int m=2;Perm(a,0,2);} 

4 字符串定位:返回字符串str,在字符串dest中出现的位置(第一个字母),没有出现则返回-1 int locate(char* str, char* dest) 例如 locate( “abc”, “fadbabdabcda”) 则返回7

滑动窗口

int slideToSubString_III(string str, string sub) {int i = 0, j = 0;int index = 0;while (i < str.length() && j < sub.length()) {if (str[i] == sub[j]) {i++;j++;} else {i = i - j + 1;j = 0;}if (j == sub.length()) {return i - j;}}return 0;
}

难度:4

1 计算正确的四则整形运算表达式的值。输入一个正确四则整形运算表达式字符串,输出计算结果(除法可以直接执行整数除,不考虑小数,如5/4等于1)。如输入“(17+3)/4+2",输出7。

#include 
#include 
#include 
#include using namespace std;stack op;
stack num;
unordered_map pr = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};void eval()
{int b = num.top(); num.pop();int a = num.top(); num.pop();char c = op.top(); op.pop();int x;if(c == '+') x = a + b;else if(c == '-') x = a - b;else if(c == '*') x = a * b;else x = a / b;num.push(x);
}int main()
{string s;cin >> s;for(int i = 0; i < s.size(); i++){char c = s[i];if(isdigit(c)){int x = 0, j = i;while(j < s.size() && isdigit(s[j])) x = 10 * x + s[j++] - '0';i = j - 1;num.push(x);}else if(c == '(') op.push(c);else if(c == ')'){while(op.size() && op.top() != '(') eval();op.pop();}else{while(op.size() && pr[op.top()] >= pr[c]) eval();op.push(c);}}while(op.size()) eval();cout << num.top() << endl;return 0;
}

2 对n个等长(长度为len)的字符串进行字典顺序排序 sort_str( char* str[], int len, int n )

#include 
#include 
#include 
#include using namespace std;bool cmp(string a, string b)
{return a < b;
}int main()
{int num;string str;vector v;while (cin >> num){while (num--){cin >> str;v.push_back(str);}sort(v.begin(),v.end(),cmp);cout << endl;for (int i = 0; i < v.size(); i++){cout << v[i] << endl;}}return 0;
}

3 建立10个节点的有向图,由用户输入节点对来完成。由用户指定一个源点,输出所有与之连通的所有结点的最短路径及路径长度。

int graph[10][10];
int shortest[10];
int pred[10];
void create_graph( void )
void dijkstra( int source )
void show_shortest_path( int source )

#include 
#include 
#include 
#include using namespace std;typedef pair PII;const int N = 1e6 + 10;int n, m;
int h[N], w[N], e[N], ne[N], idx;
int dist[N];
bool st[N];void add(int a, int b, int c)
{e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}int dijkstra()
{memset(dist, 0x3f, sizeof dist);dist[1] = 0;priority_queue, greater> heap;heap.push({0, 1});while (heap.size()){auto t = heap.top();heap.pop();int ver = t.second, distance = t.first;if (st[ver]) continue;st[ver] = true;for (int i = h[ver]; i != -1; i = ne[i]){int j = e[i];if (dist[j] > dist[ver] + w[i]){dist[j] = dist[ver] + w[i];heap.push({dist[j], j});}}}if (dist[n] == 0x3f3f3f3f) return -1;return dist[n];
}int main()
{scanf("%d%d", &n, &m);memset(h, -1, sizeof h);while (m -- ){int a, b, c;scanf("%d%d%d", &a, &b, &c);add(a, b, c);}cout << dijkstra() << endl;return 0;
}

4 利用数组实现堆的三种基本操作, 插入元素:void insert( int x, int heap[], int len) 删除元素:int delete( int heap[], int len ) 更新元素:void update( int x, int pos, int heap[], int len ) x 为插入或新元素, heap为堆,len是堆的尺寸,pos是新元素的位置。

#include
#include
using namespace std;const int N=1e5+10;
int h[N];   //堆
int ph[N];  //存放第k个插入点的下标
int hp[N];  //存放堆中点的插入次序
int cur_size;   //size 记录的是堆当前的数据多少//这个交换过程其实有那么些绕 但关键是理解 如果hp[u]=k 则ph[k]=u 的映射关系
//之所以要进行这样的操作是因为 经过一系列操作 堆中的元素并不会保持原有的插入顺序
//从而我们需要对应到原先第K个堆中元素
//如果理解这个原理 那么就能明白其实三步交换的顺序是可以互换 
//h,hp,ph之间两两存在映射关系 所以交换顺序的不同对结果并不会产生影响
void heap_swap(int u,int v)
{   swap(h[u],h[v]); swap(hp[u],hp[v]);     swap(ph[hp[u]],ph[hp[v]]);            }void down(int u)
{int t=u;if(u*2<=cur_size&&h[t]>h[u*2]) t=u*2;if(u*2+1<=cur_size&&h[t]>h[u*2+1])  t=u*2+1;if(u!=t){heap_swap(u,t);down(t);}
}
void up(int u)
{if(u/2>0&&h[u]heap_swap(u,u/2);up(u>>1);}
}int main()
{int n;cin>>n;int m=0;      //m用来记录插入的数的个数//注意m的意义与cur_size是不同的 cur_size是记录堆中当前数据的多少//对应上文 m即是hp中应该存的值while(n--){string op;int k,x;cin>>op;if(op=="I"){cin>>x;m++;h[++cur_size]=x;ph[m]=cur_size;hp[cur_size]=m;//down(size);up(cur_size);}else if(op=="PM")    cout<heap_swap(1,cur_size);cur_size--;down(1);}else if(op=="D"){cin>>k;int u=ph[k];                //这里一定要用u=ph[k]保存第k个插入点的下标heap_swap(u,cur_size);          //因为在此处heap_swap操作后ph[k]的值已经发生 cur_size--;                    //如果在up,down操作中仍然使用ph[k]作为参数就会发生错误up(u);down(u);}else if(op=="C"){cin>>k>>x;h[ph[k]]=x;                 //此处由于未涉及heap_swap操作且下面的up、down操作只会发生一个所以down(ph[k]);                //所以可直接传入ph[k]作为参数up(ph[k]);}}return 0;
}

5 输入一段文本,打印输出对应的哈夫曼编码: void hfm(char str[], int len)

6 建立6个节点的无向图。由用户指定一个源点、一个终点,输出从源点到终点的所有路径及长度。

7 在2行5列的格子中填入1到10的数字。要求:相邻的格子中的数,右边的大于左边的,下边的大于上边的。请你计算一共有多少种可能的方案,并输出所有的方案。

#includeint a[2][5];
int cou = 0;
int flag[10];
int check()
{if (a[1][0] < a[0][0])return 0;for (int i = 1; i < 5; i++){if (a[0][i] < a[0][i-1]){return 0;}if (a[1][i] < a[1][i-1]){return 0;}if (a[1][i] < a[0][i]){return 0;}}return 1;
}
void DFS(int num)
{if (num == 10){if (check()){cou++;}return;}for (int i = 1; i <= 10; i++){if (flag[i] == 0){flag[i] = 1;a[num / 5][num % 5] = i;DFS(num + 1);flag[i] = 0;}}
}int main()
{for (int i = 0; i < 2; i++){for (int j = 0; j < 5; j++){a[i][j] = 0;}}for (int i = 0; i < 10; i++){flag[i] = 0;}DFS(0);printf("%d\n", cou);
}

难度:5

1 计算四则运算表达式的值。输入一个正确四则运算表达式字符串,表达式正确则输出计算结果,错误则给出提示。

在这里插入代码片

2 对n个不等长的字符串进行字典顺序排序,各字符串长度存放在数组len中 sort_str( char* str[], int len[], int n )

//这里我们引用了string.h库里的比较函数strcmp()和复制函数strpy()
#include
#include
int main()
{char a[201][201];//首先我们建立一个存放输入字符串的二维数组char b[201];//再建立一个临时存放字符串的数组int n;scanf("%d",&n);//n个字符串for(int i=0;iif(strcmp(a[i],a[j])>0)//不断比较前一个与后一个{//如果前一个字符的ASCII码大于后一个则交换位置//这个则由strcmp的值来反应,如果前一个元素大于后一个元素//则返回值1,如果相等返回值0,如果小于,返回值-1strcpy(b,a[i]);//利用临时数组存放字符串strcpy(a[i],a[j]);//将括号里的第二个元素赋给第一个元素strcpy(a[j],b);//结果是后一个与前一个交换}}for(int i=0;iprintf("%s\n",a[i]);//将每一行的字符串打印出来}
}

3 0-1背包问题。假设你有一个背包,最多能承重C千克,这里有k个物品,其重量分别为w1、w2、……、wk,在背包所能承受的重量下,尽可能得使背包里的物品重量最大。

void bag( int ball[], int n, int w)

//0-1背包问题 
#includeusing namespace std;const int MAXN = 1005;
int f[MAXN];  // int main() 
{int n, m;   cin >> n >> m;for(int i = 1; i <= n; i++) {int v, w;cin >> v >> w;      // 边输入边处理for(int j = m; j >= v; j--)f[j] = max(f[j], f[j - v] + w);}cout << f[m] << endl;return 0;
}

相关内容

热门资讯

Android App开发网络... 需要源码请点赞关注收藏后评论区留言并且私信~~~ 一、使用okhttp下载图片 okhttp不但简...
蛇能被养熟吗?一农妇与蛇窝同居... 原标题:蛇能被养熟吗?一农妇与蛇窝同居十年,泰国“毒王”却被一口咬死 夜半时...
荒野的召唤攻略(荒野的召唤攻略... 今天给各位分享荒野的召唤攻略的知识,其中也会对荒野的召唤攻略新手进行解释,如果能碰巧解决你现在面临的...
致敬翻译的力量——第二届雅努斯... 原标题:致敬翻译的力量——第二届雅努斯计划受资助名单即将揭晓 2024 致敬...
山河智能:美国轻型运动飞机市场... 原标题:山河智能:美国轻型运动飞机市场规模较大,中国市场规模稳步增长 金融界4...
马英九措辞有变, 台军宣布重启... 原标题:马英九措辞有变, 台军宣布重启实弹射击,两岸统一进入倒计时 台湾地区前...
武汉融创城楼盘怎么样,海峡创业... 随着国庆假期的到来,期待已久的8天假期迎来了!为了方便大家出行,8号线三期从10月1日起恢复正常运营...
大众收购保时捷(大众收购保时捷... 本篇文章极速百科给大家谈谈大众收购保时捷,以及大众收购保时捷了吗对应的知识点,希望对各位有所帮助,不...
西安特价酒店(西安实惠的酒店)... 本篇文章极速百科给大家谈谈西安特价酒店,以及西安实惠的酒店对应的知识点,希望对各位有所帮助,不要忘了...
红云红河烟草(集团)原董事长武... 原标题:红云红河烟草(集团)原董事长武怡被公诉! 红云红河烟草(集团)原董事...