嵌入式笔试算法题总结

0.字符串定义

char str1[] = "123456"; // 存放在栈区,可读可写
// char *str2 = "12345"; // 存放在只读数据区,不可以进行修改,需要加const进行修饰
const char *str2 = "12345";
#include <iostream>
#include <string.h>
using namespace std;

char str1[] = "123456"; // 存放在栈区,可读可写
// char *str2 = "12345"; // 存放在只读数据区,不可以进行修改,需要加const进行修饰
const char *str2 = "12345";

int main()
{
    // 字符串定义:方法3
    char *str3 = (char *)malloc(128);
    strcpy(str3, "1234");
    cout << str3 << endl;
    free(str3); // 字符串使用完之后,立即进行释放

    return 0;
}

1.字符串翻转

#include <iostream>
#include <string.h>
using namespace std;

// 字符串逆序
void Reverse(char *str)
{
    int length = strlen(str);
    for (size_t i = 0; i < length / 2; i++)
    {
        char temp = str[i];
        str[i] = str[length - 1 - i];
        str[length - 1 - i] = temp;
    }
}

int main()
{
    char str1[] = "12345";
    Reverse(str1);
    cout << str1 << endl;  // 54321
    return 0;
}

2.字符串排序

描述:随便输入几个字母,按照a~z顺序排列,采用冒泡排序算法进行设计

#include <iostream>
#include <string.h>
using namespace std;

// 冒泡排序
void BubbleSort(char arr[], int n)
{
    for (int i = 0; i < n - 1; i++)
    {
        int flag = 0;
        for (int j = 0; j < n - 1 - i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                char temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;

                flag = 1;
            }
        }
        if (flag == 0)
        {
            break;
        }
    }
}

int main()
{
    char str[] = "AaBbcC";
    int n = strlen(str);
    BubbleSort(str, n);
    cout << str << endl; // ABCabc

    return 0;
}

3.统计汉字和字母的个数

注意:使用GBK编码,使用UTF-8编码,程序计算结果有误

  • 在UTF-8编码中,一个汉字占3个字节
  • 在GBK编码中,一个汉字占2个字节
#include <iostream>
using namespace std;

// 统计汉字和字母的个数
void Count(char arr[])
{
    int i = 0;
    int zh = 0;
    int en = 0;
    while (arr[i]) // 执行到结束符\0
    {
        if (arr[i] < 0) // 一个汉字由两个小于0的字符组成
        {
            zh++;
            i += 2;
        }
        else
        {
            en++;
            i++;
        }
    }
    cout << "zh = " << zh << endl;
    cout << "en = " << en << endl;
    cout << "sum = " << zh + en << endl;
}

int main()
{
    char str[] = "C++汉字";
    Count(str);
    return 0;
}

4.打印9*9乘法表

#include <iostream>
using namespace std;

int main()
{
    for (short i = 1; i <= 9; i++)
    {
        for (short j = 1; j <= i; j++)
        {
            cout << i << "x" << j << "=" << i * j << "\t";
        }
        cout << endl; // 完成一行后,进行换行
    }
    return 0;
}

5.将字符串中的大写字母转化为小写字母

ASCII:A(65)、a(97),a - A  = 32

#include <iostream>
#include <string.h>
using namespace std;

// 字符串中大小写切换
void Shift(char arr[], int n)
{

    for (int i = 0; i < n; i++)
    {
        // 大写转小写
        if (arr[i] >= 'A' && arr[i] <= 'Z')
        {
            arr[i] += 32;
        }

        // 小写转大写
        else if (arr[i] >= 'a' && arr[i] <= 'z')
        {
            arr[i] -= 32;
        }
    }
}

int main()
{
    char str[] = "ABab";
    int n = strlen(str);
    Shift(str, n);
    cout << str << endl;
    return 0;
}

6.计算2的1024次方

  • 在C语言中,int型占4个字节,4*8 = 32位,最大表示2的32次方-1。
  • 方法:定一个大的数组(初始化为1),把数字当作字符串进行处理,模拟2进位的方法,最终得到的字符串进行逆序。
#include <iostream>
#include <string.h>
using namespace std;

// 字符串逆序
void Reverse(char *str)
{
    int length = strlen(str);
    for (size_t i = 0; i < length / 2; i++) // 由于要进行逆序,所以只需要交换前一半的字符即可
    {
        char temp = str[i];
        str[i] = str[length - 1 - i];
        str[length - 1 - i] = temp;
    }
}

// 计算2的N次方
void Index(int n, char *str)
{
    int i, j;
    for (i = 0; i < n; i++)
    {
        int temp = 0; // 用于保存进位的临时变量
        for (j = 0; j < strlen(str); j++)
        {
            int num = str[j] - '0';  // 将字符转换为对应的整数值
            num = (num << 1) + temp; // 将当前位的数乘以2,并加上进位
            temp = num / 10;         // 计算进位
            str[j] = num % 10 + '0'; // 将计算结果转换回字符型,并存储
        }
        if (temp > 0)
        {
            str[j] = temp + '0'; // 如果还有进位,存储在新的一位上
        }
    }
    Reverse(str); // 计算完成后,需要将字符串逆序,得到正确的结果
}

int main()
{
    int n = 16;
    char str1[n] = {'1'};
    Index(n, str1);
    cout << str1 << endl; // 65536
    return 0;
}

7.数组元素逆序

#include <iostream>
using namespace std;

// 数组元素逆序
void Reverse(int arr[], int n)
{
    for (int i = 0; i < n / 2; i++)
    {
        int temp = arr[i];
        arr[i] = arr[n - 1 - i];
        arr[n - 1 - i] = temp;
    }
}

int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr) / sizeof(int);
    Reverse(arr, n);

    for (int i = 0; i < n; i++)
    {
        cout << arr[i] << ",";
    }
    cout << endl;
    return 0;
}

8.宏定义

宏定义,防止头文件被重复编译

// 标识符可以自由命名,一般使用头文件名全部大写的方式,前面加_,把.改成_
#ifndef _LED_H  
#define _LED_H
// 代码段
#endif

宏定义函数,带参

#include <iostream>
using namespace std;

#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))

int main()
{
    int a = MAX(1, 2);
    cout << a;
    return 0;
}

通过宏定义的方式,计算数组的长度 

#include <iostream>
using namespace std;

#define Len(arr) (sizeof(arr) / sizeof(arr[0]))

int main()
{
    int a[] = {1, 2, 3};
    int b = Len(a);
    cout << b;
    return 0;
}

9.不使用sizeof判断操作系统是64位还是32位

#include <stdio.h>

int main() {
    if ((1L << 32) == 0) {
        printf("64位系统\n");
    } else {
        printf("32位系统\n");
    }
    
    return 0;
}

10.如何判断链表是否有环

正常的单向链表,最后一个节点的指针域应该是NULL,表示后面没有节点。

如果把最后一个节点的指针域,改为前面的某个节点的地址,这样的链表叫做有环的链表。

如何判断链表是否有环:

1.定义两个指针:慢指针(每次走一步)、快指针(每次走两步)

2.如果链表没有环,快的指针肯定最先到达终点

3.如果链表有环,那么两个指针迟早相遇

int fcn(Node *head)
{
    if (head == NULL)
    {
        return 0;
    }

    Node *fast = head;
    Node *slow = head;

    while (fast && slow) // 两个指针都不为空
    {
        // 如果某个指针为空,说明链表没有环
        if (fast->next && fast->next->next)
        {
            fast = fast->next->next; // 快指针每次走两步
        }
        else
            break;
        if (slow->next)
        {
            slow = slow->next; // 慢指针每次走一步
        }
        else
            break;
        if (fast == slow) // 如果快慢指针在某个时刻相等,说明链表有环
            return 1;     // 链表有环
    }
    return 0; // 链表没有环
}

 11.如何判断两个链表是否相交

如果两个链表相交,那么一定有重合的节点。

方法1:可以逐个判断第一个链表里面的节点,是否在第二个链表中。效率较低

方法2:相交的两个链表,他们的最后一个节点一定是重合的,所以只要让第一个链表的指针,指向最后一个节点。第二个链表的指针,也指向最后一个节点,判断这两个节点是否相同。

int is_cross(Node *head1, Node *head2)
{
    if (head1 == NULL || head2 == NULL)
    {
        return 0;
    }

    Node *p1 = head1, *p2 = head2;
    // 假设链表有头节点,两个指针分别移动到最后一个节点
    // 如果指针相同,那链表就是相交的
    while (p1->next)
    {
        p1 = p1->next;
    }
    while (p2->next)
    {
        p2 = p2->next;
    }
    if (p1 == p2)
    {
        return 1; // 链表相交
    }
    else
        return 0; // 链表不相交
}

 进阶:如何找出相交的那个节点

如果两个链表的长度一样,只要同时移动指针,最先相等的那个节点,一定就是相交的节点,所以可以先计算两个链表的长度差,然后先移动一个指针,保证长度一样后再同时向后走。 

 12. 手写链表的基本操作

链表的初始化、插入、遍历

链表相对于数组的优点:容量没有限制,插入删除的效率比较高。数组在内存中是一块连续的存储空间,链表在内存中不连续,由节点组成,每个节点包含两部分(数据域:存储数据,指针域:存储下一个节点的地址) 

链表的初始化:空链表,只有一个头节点,没有数据域

#include <iostream>
using namespace std;

typedef struct Node
{
    int data;
    struct Node *next;
} Node;

// 链表的初始化
int InitList(Node **h)
{
    if (h == NULL)
    {
        return 0;
    }
    (*h) = (Node *)malloc(sizeof(Node));
    if ((*h) == NULL)
        return 0;
    (*h)->next = NULL;
    return 1;
}

int main()
{
    Node *head = NULL; // 链表的初始化:形成一个空的链表

    int ret = InitList(&head);
    if (ret == 0)
        cout << "链表初始化失败" << endl;
    else
        cout << "链表初始化成功" << endl;

    return 0;
}

13.找出字符串中不含有重复字符的最长子串的长度

例如,abcabcbb的无重复字符的最长子串是“abc”

#include <iostream>
using namespace std;

int lengthofLongestSubstring(char *s)
{
    int exist[256] = {0};
    char *left = s;
    char *right = s;
    int max = 0;

    while (*right != 0)
    {
        if (exist[*right] == 1)
        {
            exist[*left++] = 0;
        }
        else
        {
            exist[*right++] = 1;
            int t = right - left;
            if (t > max)
                max = t;
        }
    }
    return max;
}

int main()
{
    char str[] = "abcabcdd";
    int a = lengthofLongestSubstring(str);
    cout << a << endl; // 输出4

    return 0;
}

14.将字符串转化为整数

#include <iostream>
#include <string.h>
using namespace std;

// 将字符串转换为整数
void Conver_Int(char str[], int &num)
{
    int len = strlen(str);
    cout << "str len = " << len << endl;

    for (int i = 0; i < len; i++)
    {
        if (str[i] > '0' && str[i] < '9')
        {
            // 将字符转换为整数
            int temp = str[i] - 48;  // 0的ASCII为48
            num = num * 10 + temp;
        }
    }
}

int main()
{

    char str[] = "123456";
    int num = 0;
    Conver_Int(str, num);
    cout << num + 1 << endl; // 输出123457
    return 0;
}

15.将整数转化为字符串

#include <iostream>
using namespace std;

void Int_String(int num, char str[])
{
    int i = 0;
    int isNegative = 0;

    // 处理负数
    if (num < 0)
    {
        isNegative = 1;
        num = -num; // 如果是负数,将其转为正数
    }
    // 处理特殊情况:整数为0
    if (num == 0)
    {
        str[i++] = '0'; // 如果整数为0,将字符'0'存入字符串
    }

    // 将整数转换为字符串(从右到左)
    while (num > 0)
    {
        int digit = num % 10;   // 取出整数的最后一位数字
        str[i++] = '0' + digit; // 将数字字符存入字符串
        num /= 10;              // 移除最后一位数字
    }

    // 如果是负数,添加负号
    if (isNegative)
    {
        str[i++] = '-'; // 如果是负数,添加负号到字符串
    }

    str[i] = '\0'; // 在字符串末尾添加 null 终止字符

    // 反转字符串,因为上面的循环是从右到左构建的
    int len = i; // 计算字符串的长度
    for (int j = 0; j < len / 2; j++)
    {
        char temp = str[j]; // 交换字符的位置
        str[j] = str[len - j - 1];
        str[len - j - 1] = temp;
    }
}

int main()
{
    int num = -12345;
    char str[20];

    Int_String(num, str);
    cout << str << endl; // 输出字符串-12345

    return 0;
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值