code:
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *next;
* struct Node *random;
* };
*/
// 在每个节点后面复制一个节点
// 修改每个新节点的random指针
// 拆解节点组成新链表
struct Node* copyRandomList(struct Node* head) {
struct Node* cur = head;
// 链接新节点
while(cur)
{
struct Node* next = cur->next;
struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
copy->val = cur->val;
//改变cur节点和copy节点的指针
cur->next = copy;
copy->next = next;
cur = next;
}
// 修改新节点的random
cur = head;
while(cur)
{
struct Node* copy = cur->next;
if(cur->random!=NULL)
{
copy->random = cur->random->next;//copy的random指向下一个copy
}
else
{
copy->random = NULL;//将最后一个copy节点的random置为空
}
cur = copy->next;
}
// 解拷贝点,链接拷贝节点
struct Node* newhead = NULL,*newtail = NULL;
cur = head;
while(cur)
{
struct Node* copy = cur->next;
struct Node* next = copy->next;
//尾插copy节点
if(newtail == NULL)
{
newtail = newhead = copy;
}
else
{
newtail->next = copy;
newtail = copy;
}
//断开原节点指针
cur->next = next;
cur = next;
}
return newhead;
}
总结:
- 理清思路再写代码会很快
- 在画图理解的时候,应该标明步骤,可以借助流程图来帮助
- 在断开链表节点的时候,应该留意前后指针指向
- 可以将指针理想化为一个箭头。
code:
#include <stdio.h>
int main() {
int N = 0;
scanf("%d",&N);
char tmp[13] = { 0 };
int k = 0,i = 0;
while(N)
{
if(k!=0 && k%3==0)
{
tmp[i++] = ',';
}
tmp[i++] = N%10 + '0';//数字加上‘0’就是字符数字
N /= 10;
k++;
}
for(int j = i-1; j >= 0;--j)//因为i是后置++,所以j = i-1
{
printf("%c",tmp[j]);
}
return 0;
}
总结:
- 将数字存储在字符数组中,这种方法很值得借鉴
- 利用ASCII码巧妙转换字符和数字:数字+‘0’等于字符数字
- 为什么if后面用else就不行呢?
code:
//查找字符是否存在
//存在就不输出,不存在就输出
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
bool check_ch(char* str, char ch)
{
for(int i = 0; i < strlen(str); i++)
{
if(str[i] == ch)
{
return false;
}
}
return true;
}
int main() {
char str1[100] = {0};
char str2[100] = {0};
gets(str1);
gets(str2);
int i = 0;
while(i < strlen(str1))
{
if(check_ch(str2, str1[i]))
printf("%c",str1[i]);
++i;
}
return 0;
}
总结;
- 输入字符串直接使用gets()函数更方便
- 函数封装单独一个功能能使主体逻辑更清晰
- 对于一些代码的细节方面处理还不熟练
- 主体逻辑知道了,但是细分代码实现细节还是不清楚,思路不清晰,应该多多梳理细节上的逻辑
四:
矩阵转置
code:
#include <stdio.h>
int main()
{
int a, b;
scanf("%d %d",&a,&b);
int arr[10][10] = { 0 };
// 正常打印数组
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
scanf("%d", &arr[i][j]);
}
}
// 反转并打印数组
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
printf("%d ", arr[j][i]); // 注意这里的更改
}
printf("\n");
}
return 0;
}
总结:
- 有输出的时候,可以不用存直接按照啊题目输出结果就可以了。
code:
// #include <stdio.h>
// #include <string.h>
// int main() {
// int n1, n2, count = 0;
// scanf("%d %d", &n1, &n2);
// // 遍历n1到n2之间的所有整数
// for (int i = n1; i <= n2; i++) {
// // 转换整数为字符串
// char tempStr[20]; // 假设数字不会太大,足够存储转换后的字符串
// sprintf(tempStr, "%d", i); // 将整数i转换为字符串
// // 遍历字符串,统计数字2的个数
// for (int j = 0; tempStr[j] != '\0'; j++) {
// if (tempStr[j] == '2') {
// count++;
// }
// }
// }
// printf("%d", count);
// return 0;
// }
//第二种方法:暴力遍历
#include <stdio.h>
//统计每个数字中存在2的个数
int count_2(int num)
{
int count = 0;
while(num)
{
int tmp = num%10;
if(tmp == 2)
{
count++;
}
num /= 10;
}
return count;
}
int main()
{
int n1, n2, count = 0;
scanf("%d %d", &n1, &n2);
int c = 0;
for(int i = n1; i <= n2; i++)
{
c += count_2(i);
}
printf("%d",c);
return 0;
}
总结:
- 将数字转换成数字字符的方法:巧妙利用sprintf()来实现转换
- 对于一些小的功能模块单独写出来,养成习惯,习惯封装功能函数是逻辑更加清晰