cmake 学习笔记
hello world
#CMakeLists.txt
PROJECT (HELLO)
SET (SRC_LIST hello.cpp)
MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is Source dir " ${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello ${SRC_LIST})
# include <iostream>
int main(){
std::cout << "hello cmake" << std::endl;
return 0;
}
以下内容均不考虑 xxx复杂度,只解决需求问题,先有需求,再优化
题目
给定一个字符串,删除指定字符,然后形成一个新的字符串
intput
"abaabaaabbaaaa"
target -> b
out
"aaaccaaxaztaaua"
// 初始化i和j变量,用来当循环计数
int i=0,j=0;
// 字符串
char strings[]="abaabaccaaxbbaztaaua";
printf("origin string is: ");
while (strings[i++] != '\0') {
printf("%c", strings[i]);
}
i=0;
// 遍历的字符串不等于\0,就让它一直输出
while(strings[i]!='\0'){
// 不等于指定的字符,就让它追加到之前数组里去
if(strings[i]!='b'){
strings[j++]=strings[i];
}
// 每次自加 1
++i;
}
// 循环结束添加一个结束标记
strings[j]='\0';
// 遍历字符串的函数和上同
输入两个字符串s1,s2,并从s1中删除s2中出现的字符。。。如下描述
intput:
char s1[300] = "abcaa63akdfk";
char s2[300] = "ayk5";
output:
bc63df
需求分析:
/**
* char s1[300]="abcaa63akdfk";
* char s2[300]="ayk5";
* modify -> bc63df
* 第一次 提取 a 出来判断s1中是否存在 字符 a
* 第二次 提取y ,判断 s1中是否存在 字符y
* 第三次 提取k 判断 s1中是否存在 字符k
* 第三次 提取 5 判断 s1中是否存在 字符5
* 结束循环
*
* @param s1
* @param s2
*/
不用指针的方法
void modify(char s1[300], char s2[300]) {
// 初始化循环条件
int i = 0, j = 0, k = 0;
// 外层循环的初始条件可以忽略不写,但在内循环结束时要让k i自加一次
for (; s2[i] != '\0'; i++) {
// 内层循环的初始条件就是让s1下标置0,然后每一次循环,都去和s2做判断,
for (j = k = 0; s1[j] != '\0'; j++) {
// 这里就是判断
if (s1[j] != s2[i]) {
// 把s1中没用的元素再写进s1...
s1[k++] = s1[j];
}
}
// s1的末尾加上\0,表示结束,然后继续执行循环
s1[k] = '\0';
}
printf("modify string is:%s\n", s1);
}
/***
* 数组排序---选择排序
* 描述:
* 在待排序中的一组数据中,选出最大或者最小的数,和第一个作比较
* 找到之后进行交换
* 外层循环移动到下一位,再和之后的所有数作比较
* @param arr
* @param n
*/
void selection_sort(int arr[], int len) {
printf("origin arr is:");
for (int i = 0; i < len; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
// 定义一个计数器
int min = 0;
// 定义一个循环计数器
int i, j;
// 从0开始
for (i = 0; i < len - 1; i++) {
min = i;
// 从1开始
for (j = i + 1; j < len; j++) {
// 如果发现最小的数,就记录,最后a[min]再去和a[i]做交换,即完成排序
if (arr[j] < arr[min]) {
// 记录最小值的位置
min = j;
}
}
// 交换函数
swap(&arr[min], &arr[i]);
}
printf("modify arr is:");
for (int k = 0; k < len; ++k) {
printf("%d ", arr[k]);
}
}
快速排序
#include <iostream>
#include <cstring>
#include <algorithm>
const int N = 1e5;
using namespace std;
void quick_sort(int q[], int l, int r){
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[l + r >> 1];
while (i < j){
//这里的while等价于 do-while写法,总是要移动指针到下一个目标,再判断条件
while (q[++i] < x);
while (q[--j] > x);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j), quick_sort(q, j + 1, r);
}
int main(){
int n=0,arr[N];
cin >> n;
for (int i = 0; i < n; i ++ ){
cin >> arr[i];
}
quick_sort(arr,0,n-1);
// 遍历数组
for (int i = 0; i < n; i ++ ){
cout << arr[i] << " ";
}
return 0;
}
int arr[5]={0,2,4,6,8};//在main函数中定义
插入排序
/**
* 通过比较当前下标数和下标-1的数,使用m来记录当前下标的数据,将它和后面的数做比较,满足条件就交换,反之不交换,
* 使用一个待排序的数列来举例:
* 0,2,4,6,8
* 第一次选择下标为1的数据,将其和下标-1的数据做比较(也可以理解为下标的左边,这样会更容易理解),满足条件则交换,反之不交换
* 可以认为前面排序好的数是有序数列,对于要比较的数,它的下标每次都向后移动一位,
* 再将它和左边的数(也可以理解为前面的数)做比较
*
* @param arr
*/
void insert_sort(int arr[]){
int m,j;
for (int i = 1; i < 5; ++i) {
m=arr[i];
j=i-1;
while(j>=0 && m>arr[j]){
arr[(j--)+1]=arr[j];
// j--;
}
arr[j+1]=m;
for (int k = 0; k < 5; ++k) {
cout << arr[k] << " ";
}
cout << endl;
}
for (int i = 0; i < 5; ++i) {
cout << arr[i] << " ";
}
}
output:
2 0 4 6 8
4 2 0 6 8
6 4 2 0 8
8 6 4 2 0
8 6 4 2 0 (这个是排序后的结果,降序)
数组反转
给定一个数组,将其逆序输出
1-200的素数(质数)
需求分析
2%2
3%2
4%2 4%3
5%2 5%3 5%4
.......
200%2==0,--->> break;
// 穷举法
// count计数标记,和flag标记 0,1
int count = 0;
int flag = 0;
// 外循环2-200
for (int i = 2; i < 201; ++i) {
// 内循环
for (int j = 2; j < i; ++j) {
// 将外循环不断除内循环 内循环要小于外循环
if (i % j == 0) {
// 如果模为,直接break,跳出当前循环,flag一直置1
flag = 1;
break;
} else {
// 如果不满足以上条件,falg置0
flag = 0;
}
}
if (flag == 0) {
// 当flag为0,则计数
printf("%d ", i);
count++;
}
}
printf("\nprime have :%d\n\n\n", count);
最大公约数和最小公倍数
/**
* 最小公倍数
* 暴力求解,用k做计数k累加到一定的数后,
* 分别除需要判断的数,==0即为目标数,
* 然后break跳出循环,即为最终解。
* k=0 或 k=1都可以,如果用
* 目前能想到的最简写法
*/
int p = 11, q = 65;
int count = 0;
while (count++ < (p * q)) {
if (count % q == 0 && count % p == 0) {
printf("最小公倍数%2d", count);
break;
}
}
/**
* 最大公约数
* 辗转相除法 求最大公约数
* 当b为0的时候,就不满足条件
* 当一个小数 取模 模不过大数 时候他们会发生交换
* 目前最简写法
*/
int a = 24, b = 12, c;
while (b) { //运算
c = a % b;
a = b;
b = c;
}
printf("\n最大公约数是%d\n", a);
二分/折半查找
code:
/**
*
* @param arr
* @param l
* @param r
* @param s
*
* 二分/折半查找,针对有序数组来说
* 开始先比较这个有序数组中间的元素,如果小与中间元素,则将要查找的数据锁定在 [ l,mid ]区间内
* 大于中间元素,则将要查找的数据锁定在 [ mid+1,r ]这个区间内
*
*/
void binsearch(int arr[], int l, int r, int s) {
// if (l == r) return;
// check是判断是否满足条件的标志
// count作为计数器,找这一个数需要循环多少次
int mid = 0, check = 0,count=0;
while (l < r) {
++count;
mid = l+r >>1;
if (s > arr[mid]) {
l = mid + 1;
} else if (s < arr[mid]) {
r = mid - 1;
} else {
// 找到了指定的数,if条件就不成立,将check置为1,用来标记真
check = 1;
break;
}
}
if (check == 1) {
cout << s <<" Found ,index is " << mid << endl ;
cout<< count;
} else{
cout << s << " no found!" << endl ;
cout << count;
}
}
example:
int arr[13] = {1, 2, 3, 6, 11, 22, 25, 36, 45, 56, 58, 60, 61}, s = 61;
binsearch(arr, 0, 13, s);
output:
61 found,index is 12
测试样例均以通过
c程序设计试题汇编我觉得有问题的地方
c程序设计试题汇编(第三版)参考答案错误
第六章 数组
6.70,和 6.71
我用clion编译器跑出来的结果如下:
code:
int a[5],max=0,min=0,i=0,j=0,k=0;
for (i=0;i<5;i++){
cin >> a[i];
}
min=a[0];
for (i=1;i<5;i++){
if(a[i]<min){
min=a[i];
// 原题答案 i=j=k 是什么鬼?
// i=j=k;
j=i;
}
}
max=a[0];
for (i=1;i<5;i++){
if(a[i]>max){
max=a[i];
k=i;
}
}
a[j]=max;
a[k]=min;
cout << "The position of min is:" << " " << k <<endl;
cout << "The position of min is:" << " " << j <<endl;
for (i=0;i<5;i++){
cout << a[i] <<" ";
}
input:
6 2 3 1 0
output:
The position of min is: 0
The position of min is: 4
0 2 3 1 6
6.71
int i,f[10];
f[0]=f[1]=1;
for(i=2;i<10;i++){
f[i]=f[i-2]+f[i-1];
}
for (i=0;i<10;i++){
if(i%4==0){
cout << endl;
}
cout << f[i]<< " ";
}
//以上写法等价于c语言 cout等于 printf
output:
1 1 2 3
5 8 13 21
34 55
c++结构体
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
struct person{
int id;
char name[20];
double score;
};
int main() {
person myfriend1[3];
for (int i = 0; i < 3; ++i) {
cout << "Please input " << i+1 << " id:";
cin >> myfriend1[i].id;
cout << "Please input " << i+1 << " name:";
cin >> myfriend1[i].name;
cout << "Please input " << i+1 << " score:";
cin >> myfriend1[i].score;
}
// cout << " " << myfriend1.id << " " << myfriend1.name << " " << myfriend1.score;
for ( int i=0;i<3;i++ )
cout << i+1 << ". " << " " << myfriend1[i].id << " " << myfriend1[i].name << " " << myfriend1[i].score << endl;
return 0;
}
output:
Please input 1 id:1
Please input 1 name:leeyangyang
Please input 1 score:100
Please input 2 id:2
Please input 2 name:leeyangyang
Please input 2 score:101
Please input 3 id:3
Please input 3 name:leeyangyang
Please input 3 score:103
1. 1 leeyangyang 100
2. 2 leeyangyang 101
3. 3 leeyangyang 103
动态单向链表
https://github.com/leeyangyangy/difficult_to_understand/tree/studentManager-dev
代码水平一般,如有问题,请大佬指正。
#include <iostream>
#include <vector>
#include <cstring>
#include <memory>
using namespace std;
/**
* 在c++中,可以间接的将struct认为是class
*/
/**
* 测试数据:
* 10 20 30 40 50 60 70 80 90 100 0
*
* 查找元素:
* 520
*
* 删除元素:
* 50
*
* 添加元素
* 尾插 110 ok
*
*
*/
struct linknode{
int val;
linknode *next;
};
//函数声明
void printfLinkNode(linknode *p);
linknode *creatLinkNode(void);
linknode *delLinkNode(linknode *head,int del);
linknode *insertLinkNode(linknode *head,int insert,int site);
linknode *modifyData(linknode *head,int before_modify,int after_modify);
void searchLinkNode(linknode *head,int searchData);
int main() {
// 正常链表
cout << "----You input the linklist:----" << endl;
/**
* test data
* 10 20 30 40 50 0
*/
linknode *current=creatLinkNode();
printfLinkNode(current);
cout << endl << "----del element after the linklist:----" << endl;
/**
* test data
* 10 20 30 40 50 0
*/
current=delLinkNode(current,50);
printfLinkNode(current);
cout << endl << "----you insert after linklist----" <<endl;
/**
* test input data
* 10 20 30 40 50 0
*/
current = insertLinkNode(current,50,40);
printfLinkNode(current);
cout << endl << "----you modify after linklist----" <<endl;
/**
* test input data
* 10 20 30 40 50 0
*/
current = modifyData(current,40,520);
printfLinkNode(current);
searchLinkNode(current,520);
return 0;
}
// 遍历链表
void printfLinkNode(linknode *head){
while(head!= nullptr){
cout << head->val << " ";
head=head->next;
}
}
linknode *creatLinkNode(void){
// 定义头节点
linknode *head= new linknode;
linknode *current =new linknode;
linknode *ln = new linknode;
// new class/struct
// head= new linknode;
// head->val=110;
// head->next= nullptr;
// 插入元素到链表
// current = head;
head= nullptr;
cout << "请输入一个整形数据(输入0结束): " << endl;
cin >> current->val;
while (current->val!=0){
// 判断链表是否存在
if(head== nullptr){
// 拿到current记录的地址
head=current;
} else {
ln->next=current;
}
ln=current;
current = new linknode;
cin >> current->val;
}
// 结尾补上一个尾巴
ln->next= nullptr;
return head;
}
/**
* 删除操作思路:
* 找到元素后,把当前的
* @param head
* @param del
* @return
*/
linknode *delLinkNode(linknode *head,int del){
linknode *prev,*current=head;
cout << "head add = " << head->next << " head->val = " << head->val<< endl;
while (current!= nullptr){
cout << "current->next add = " << current->next << " " << "current->val = " << current->val << endl;
if(del==current->val){
/**
* 通过调试可以知道,p1现在的位置是上一个地址,
* p2现在指在下一个地址上
* 我们找到的这个元素把下一个也就是p2的地址给指向p1
*
*/
prev->next=current->next;
break;
} else{
prev=current;
current=current->next;
}
}
// cout << "current->next add = " << cu current->next << " " << "current->val = " << current->val << endl;
return head;
}
//指定位置插进去
linknode *insertLinkNode(linknode *head,int insert,int site){
// 创建两个指针,current指向head头指针
linknode *current=head;
// 开辟一个内存空间
linknode *ln=new linknode;
ln->val=insert;
// 记录位置 判断链表是否为空
while(current->next!= nullptr){
// 找位置插进去
if(site==current->val){
ln->next=current->next;
current->next=ln;
break;
} else{
// current向后移动
current=current->next;
}
}
// 在末尾插入
if(current->next == nullptr){
ln->next=current->next;
current->next=ln;
}
return head;
}
//改指定的元素
linknode *modifyData(linknode *head,int before_modify,int after_modify){
linknode *current=head;
while (current!= nullptr){
if(before_modify==current->val){
// 找到后修改
current->val=after_modify;
break;
}else{
// 指针向后移动
current=current->next;
}
}
return head;
}
//查找指定元素
void searchLinkNode(linknode *head,int searchData){
linknode *current=head;
int flag=0;
while(current->next!= nullptr){
if(current->val==searchData){
flag=1;
break;
} else{
current=current->next;
}
}
if(flag==1){
cout << endl << searchData << " Found!";
}else{
cout << endl << searchData << " No Found!";
}
}
void menu(){
cout << "-------欢迎使用学生管理系统--------";
/**
* 正常的尾插数据
*/
cout << "--------1.添加学生---------------";
/**
* 搜索进行删除
*/
cout << "--------2.删除学生---------------";
/**
* 读取文件
*/
cout << "--------3.打开文件---------------";
/**
* 直接删除整个保存的数据
*/
cout << "--------4.删除数据(不可逆操作,谨慎!)";
/**
* 文件以乱序形式存储,打开后按需进行排序
*/
cout << "--------5.保存数据---------------";
}
output:
----You input the linklist:----
请输入一个整形数据(输入0结束):
10 20 30 40 50 0
10 20 30 40 50
----del element after the linklist:----
head add = 0x1bf26d11c80 head->val = 10
current->next add = 0x1bf26d11c80 current->val = 10
current->next add = 0x1bf26d11ca0 current->val = 20
current->next add = 0x1bf26d11cc0 current->val = 30
current->next add = 0x1bf26d11ce0 current->val = 40
current->next add = 0 current->val = 50
10 20 30 40
----you insert after linklist----
10 20 30 40 50
----you modify after linklist----
10 20 30 520 50
520 Found!
------目前已知问题,不能删除头节点元素------
重新学过的数据结构基础
单循环链表
#include <iostream>
using namespace std;
//定义一个结构体
typedef struct Node {
int data;
struct Node *next;
} Node;
//初始化单循环链表
Node *initList() {
// 开辟内存空间
Node *L = (Node *) malloc(sizeof(Node));
// 头节点记录节点数
L->data = 0;
// 指向自己
L->next = L;
// 返回链表
return L;
}
//函数声明(头插,尾插,删除,排序)
void headInsert(Node *L, int data);
void tailInsert(Node *L, int data);
void deleteList(Node *L, int data);
void printList(Node *L);
void sortList(Node *L);
int main() {
// 初始化空链表
Node *L = initList();
headInsert(L, 3);
tailInsert(L, 0);
headInsert(L, 2);
tailInsert(L, -3);
headInsert(L, 1);
tailInsert(L, -1);
tailInsert(L, -2);
headInsert(L, 4);
printList(L);
// deleteList(L, 0);
// deleteList(L, 4);
// deleteList(L, -3);
sortList(L);
printList(L);
return 0;
}
/**
*
* @param L
* @param data
* description:头插法
*/
void headInsert(Node *L, int data) {
// 开辟新内存空间
Node *node = (Node *) malloc(sizeof(Node));
// 接收传进来数据
node->data = data;
// 断开链表,让其指向原先的节点
node->next = L->next;
// 头节点指向下一节点
L->next = node;
// 节点数+1
++L->data;
}
/**
*
* @param L
* @param data
* description:尾插法
*/
void tailInsert(Node *L, int data) {
// 开辟内存空间
Node *node = (Node *) malloc(sizeof(Node));
Node *current = (Node *) malloc(sizeof(Node));
// 赋值
node->data = data;
current = L->next;
while (current->next != L)
// 移动指针
current = current->next;
// 指向L头节点
node->next = L;
// 加入node节点
current->next = node;
// 节点数++
++L->data;
}
/**
*
* @param L
* @param data
* description: 删除链表中指定元素
*/
void deleteList(Node *L, int data) {
//删除节点不需要开辟内存空间
Node *node = L->next;
Node *prev = L;
// 移动链表
while (node != L) {
if (node->data == data) {
prev->next = node->next;
// 释放内存
free(node);
// 记录节点数
--L->data;
// 结束循环
return;
}
prev = node;
// 移动节点
node = node->next;
}
}
/**
*
* @param L
* description:遍历
*/
void printList(Node *L) {
// 打印链表个数
cout << "linklist have " << L->data << "\n";
Node *node = L->next;
while (node != L) {
cout << node->data << " => ";
node = node->next;
}
cout << "NULL\n";
}
/**
* 有点怪的排序,想到啥写啥,主要思路是冒泡排
* @param L
*/
void sortList(Node *L) {
// 冒泡排序
Node *node = L->next;
// temp
int temp = 0;
// 因为是循环链表,所以node节点循环到尾巴的时候它的指向是头节点,所以此处的条件是不等于头节点L
while (node != L) {
// 这里没有做优化,每次都会重头开始判断,对于冒泡排序来说,头部经过排序后,一定是符合要求的,还有优化空间
for (Node *prev = L->next;prev->next!=L;prev=prev->next) {
// 交换元素,对于c++来说,可以使用内部swap函数进行交换元素
if(node->data<prev->data){
temp=node->data;
node->data=prev->data;
prev->data=temp;
}
}
// 移动链表
node = node->next;
}
}