笔面试编程题总结

8/6诺瓦星云

修改程序

c 复制代码
void point(int *p){*p = p[2];};
int main() {
    int c[] ={1,2,3,4,5},*p = c;
    point(p+1);
    for(;p <c+5;)
    {
        printf("%d",*p++);
    }
    return 0;
}

1、分隔字符串 strtok

c 复制代码
//c语言
#include <stdio.h>
#include <string.h>

// 函数声明
char* findLongestWord(char* str);

int main() {
    char* str = "This is a test string";
    char* longestWord = findLongestWord(str);
    if (longestWord != NULL) {
        printf("The longest word is: %s\n", longestWord);
    } else {
        printf("No words found in the string.\n");
    }
    return 0;
}

// 函数定义
char* findLongestWord(char* str) {
    if (str == NULL) return NULL; // 检查输入字符串是否为空

      //分隔
      char *token;
      char *tokens[100]; // 假设最多分割出100个子字符串
      int i = 0;
      char delimiters[] = " "; // 定义分隔符

      // 复制输入字符串,因为strtok会修改原字符串
      char *strCopy = strdup(str);

      // 用strtok分割字符串,要分割的字符串,第一次调用时传入需要分割的字符串,之后传入 NULL
      token = strtok(strCopy, delimiters);
      while (token != NULL) {
          tokens[i++] = token; // 保存分割后的子字符串
          token = strtok(NULL, delimiters); // 继续获取下一个子字符串
      }

      // 打印分割后的结果
      int max = -1;
      char* longestWord = NULL; // 指向最长单词的指针
      for (int j = 0; j < i; j++) {
          //printf("%s\n", tokens[j]);
          int len_tmp = strlen(tokens[j]);
          if(len_tmp>max){
              max = len_tmp;
              longestWord = tokens[j];
          }
      }

      // 释放复制的字符串
      free(strCopy);

    return longestWord;
}

2、后缀法解 最长无重复子串

c 复制代码
//C 最长无重复子串
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//得到字符串最长的无重复的前缀长度
int longestlen(char * p)
{
    int hash[256];
    int len = 0;
    memset(hash,0,sizeof(hash));
    while (*p && !hash[*p])
    {
        hash[*p] = 1;
        ++ len;
        ++ p;
    }
    return len;
}

//使用后缀数组解法
int max_unique_substring4(char * str)
{
    int maxlen = -1;
    int begin = 0;
    char *a[99999];
    int n = 0;
    while(*str != '\0')
    {
        a[n++] = str++;
    }
    for (int i=0; i<n; i++)
    {
        int temlen = longestlen(a[i]);
        if (temlen > maxlen)
        {
            maxlen = temlen;
            begin = i;
        }
    }
    printf("%.*s\n", maxlen, a[begin]);
    return maxlen;
}
int main() {
    char *test_str = "abcabcbb";
    printf("Length of the longest substring without repeating characters: %s\n", max_unique_substring4(test_str));
    return 0;
}

3、双向链表

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

// 定义链表节点结构体
typedef struct list_node_t {
    struct list_node_t *p_before;  // 上一级节点
    struct list_node_t *p_next;    // 下一级节点
    void *p_data;                  // 存储数据节点
    uint32_t data_size;            // 存储数据大小
} list_node_t;

// 插入数据到链表尾部
int insert_data_to_list(void *p_list_head, const void *data, uint32_t data_size) {
    if (!p_list_head || !data) {
        return -2; // 传入指针为空错误
    }
    
    // 创建新节点
    list_node_t *new_node = (list_node_t *)malloc(sizeof(list_node_t));
    if (!new_node) {
        return -1; // 内存申请错误
    }
    
    new_node->p_data = malloc(data_size);
    if (!new_node->p_data) {
        free(new_node);
        return -1; // 内存申请错误
    }
    
    memcpy(new_node->p_data, data, data_size);
    new_node->data_size = data_size;
    new_node->p_before = NULL;
    new_node->p_next = NULL;
    
    // 找到链表尾部
    list_node_t *current = (list_node_t *)p_list_head;
    while (current->p_next) {
        current = current->p_next;
    }
    
    // 插入新节点到尾部
    current->p_next = new_node;
    new_node->p_before = current;
    
    return 0; // 正确
}

// 从链表中删除节点并释放空间
int delete_list_node(void *p_node) {
    if (!p_node) {
        return -2; // 传入指针为空错误
    }

    list_node_t *node = (list_node_t *)p_node;

    // 重新连接链表
    if (node->p_before) {
        node->p_before->p_next = node->p_next;
    }
    if (node->p_next) {
        node->p_next->p_before = node->p_before;
    }

    // 释放节点数据和节点本身
    free(node->p_data);
    free(node);
    return 0; // 正确
}

// 示例用法
int main() {
    list_node_t head = {NULL, NULL, NULL, 0}; // 初始化链表头部
    int data1 = 100;
    int data2 = 20;
    insert_data_to_list(&head, &data1, sizeof(data1));
    insert_data_to_list(&head, &data2, sizeof(data2));
    // 遍历链表并打印数据
    list_node_t *current = head.p_next;
    while (current) {
        printf("%d\n", *(int *)current->p_data);
        current = current->p_next;
    }
    // 删除所有节点
    current = head.p_next;
    while (current) {
        list_node_t *next = current->p_next;
        delete_list_node(current);
        current = next;
    }
    return 0;
}

4、背包问题

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

// 定义链表节点结构体
typedef struct list_node_t {
    struct list_node_t *p_before;  // 上一级节点
    struct list_node_t *p_next;    // 下一级节点
    void *p_data;                  // 存储数据节点
    uint32_t data_size;            // 存储数据大小
} list_node_t;

// 插入数据到链表尾部
int insert_data_to_list(void *p_list_head, const void *data, uint32_t data_size) {
    if (!p_list_head || !data) {
        return -2; // 传入指针为空错误
    }
    
    // 创建新节点
    list_node_t *new_node = (list_node_t *)malloc(sizeof(list_node_t));
    if (!new_node) {
        return -1; // 内存申请错误
    }
    
    new_node->p_data = malloc(data_size);
    if (!new_node->p_data) {
        free(new_node);
        return -1; // 内存申请错误
    }
    
    memcpy(new_node->p_data, data, data_size);
    new_node->data_size = data_size;
    new_node->p_before = NULL;
    new_node->p_next = NULL;
    
    // 找到链表尾部
    list_node_t *current = (list_node_t *)p_list_head;
    while (current->p_next) {
        current = current->p_next;
    }
    
    // 插入新节点到尾部
    current->p_next = new_node;
    new_node->p_before = current;
    
    return 0; // 正确
}

// 从链表中删除节点并释放空间
int delete_list_node(void *p_node) {
    if (!p_node) {
        return -2; // 传入指针为空错误
    }

    list_node_t *node = (list_node_t *)p_node;

    // 重新连接链表
    if (node->p_before) {
        node->p_before->p_next = node->p_next;
    }
    if (node->p_next) {
        node->p_next->p_before = node->p_before;
    }

    // 释放节点数据和节点本身
    free(node->p_data);
    free(node);
    return 0; // 正确
}

// 示例用法
int main() {
    list_node_t head = {NULL, NULL, NULL, 0}; // 初始化链表头部
    int data1 = 100;
    int data2 = 20;
    insert_data_to_list(&head, &data1, sizeof(data1));
    insert_data_to_list(&head, &data2, sizeof(data2));
    // 遍历链表并打印数据
    list_node_t *current = head.p_next;
    while (current) {
        printf("%d\n", *(int *)current->p_data);
        current = current->p_next;
    }
    // 删除所有节点
    current = head.p_next;
    while (current) {
        list_node_t *next = current->p_next;
        delete_list_node(current);
        current = next;
    }
    return 0;
}
相关推荐
程序猿进阶1 小时前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot
LCG元8 小时前
【面试问题】JIT 是什么?和 JVM 什么关系?
面试·职场和发展
GISer_Jing12 小时前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试
m0_7482455212 小时前
吉利前端、AI面试
前端·面试·职场和发展
TodoCoder14 小时前
【编程思想】CopyOnWrite是如何解决高并发场景中的读写瓶颈?
java·后端·面试
Wyang_XXX15 小时前
CSS 选择器和优先级权重计算这么简单,你还没掌握?一篇文章让你轻松通关面试!(下)
面试
liyinuo201718 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范
代码中の快捷键19 小时前
java开发面试有2年经验
java·开发语言·面试
bufanjun0011 天前
JUC并发工具---ThreadLocal
java·jvm·面试·并发·并发基础
sc写算法1 天前
Hash 映射
数据结构·算法·哈希算法