笔试算法总结二:数组和字符串

(1)、输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。

要求时间复杂度为O(n)。 如:数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2。

  解题思路:若求和最大的子数组,假设sum[i]是包含第i个元素在内的子数组,Max是当前子数组的最大和。那么对于下一个元素A[i+1],可以有以下两种可能,

      sum[i+1] = max(a[i+1], sum[i] + a[i+1])


      result = max(result, sum[i])

  代码如下:

  

#include <stdlib.h>
#include <stdio.h>

int main(char *argv[], int argc)
{
    int i = 0 ;
    int j = 0;
    int A[10] = {1, -2, 3, 10, -4, 7, 2, -5};
    int max = A[0];
    int sum = 0;
    for(i=0; i<10; i++)
    {
        if(sum >= 0)
            sum += A[i];
        else
            sum = A[i];

        if(sum>max)
            max = sum;
    }

    printf("MAX Sum:%d",max);

    system("PAUSE");
    return 0;
}
View Code

 

(2)、输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。

           例如输入“I am a student.”,则输出“student. a am I”。

       解题思路:栈可以将一个序列逆序输出,如果把单词当做一个元素,一次入栈,然后再依次出栈,得到的就是逆序结果。因为单词是以空格分隔的,我们在顺   序读取句子中的字母或者标点时,遇到空格就知道是某一个单词的结束了。把当前的单词入栈。出栈的时候,再把单词组装为句子就可以了。

  代码如下,这个代码没有严格使用栈,最后的单词组装也没有完成,不过逆序的功能已经实现。

#include <stdlib.h>
#include <stdio.h>

struct  link_node
{
    char *str;
    struct link_node *next;
};

void split_src(char *src);
void rebuild_dst(char *dst);

int main(char *argv[], int argc)
{
    char *dst = NULL;
    char *src = "I AM A ASTUDENT.";

    split_src(src);

    //rebuild_dst(dst);

//    printf("%s\n",dst);
    system("PAUSE");
    return 0;
}

void split_src(char *src)
{
    int i = 0;
    int str_len = strlen(src);
    char word[20] = {'\0'};
    int k = 0;
    struct link_node *p = NULL;
    struct link_node *head = (struct link_node *)malloc(sizeof(struct link_node));
    head->str = "";
    head->next = NULL;

    while(i<=str_len)
    {
        if(src[i] != ' ' && i<str_len){
            word[k] = src[i];
            k++;
            i++;
        }
        else {
            struct link_node *new_word = (struct link_node *)malloc(sizeof(struct link_node));
            strcpy(new_word->str,word);
            new_word->str[k] = '\0';
            new_word->next = NULL;
            
            new_word->next = head->next;
            head->next = new_word;
            printf("else:%s\n",head->next->str);
            
            for(;k>=0;k--)
                word[k] = '\0';
            k=0;
            i++;
        //    free(new_word);
        }
    }
    printf("\n");
    p = head->next;
    while(p)
    {
          char *ok = p->str;
          printf("%s  ",ok);
          p = p->next;
    }
}
View Code

 

(3)、在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。

  这个题目其实相对简单,遍历字符串,记录每个字符出现的次数,频数大于等于2的我们就不再理会就好了。

      部分代码如下:

struct statistic {
    char ch;           /*字符*/
    int  frequency;     /*是否只出现一次*/  
};

struct statistic Isonce[26];

char A[10] = {'a','b','b','c','c','d','d','d','c','c','c'};

for (i=0; i<26 ;i++ ){
    Isonce[i].ch = i+'a';
    Isonce[i].frequency = 0;
}

for (i=0;i<len ;i++ ){
    Isonce[A[i]-'a'].frequency++;
}

for (i=0;i<len ;i++ ){
    if(Isonce[A[i]-'a'].frequency == 1)
        printf("%c Comes Once\n",Isonce[A[i]-'a'].ch);
}
View Code

(4)、写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)    功能:在字符串中找出连续最长的数字串,并把这个串的长度返回,

  并把这个最长数字串付给其中一个函数参数outputstr所指内存。例如:"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回9,

  outputstr所指的值为123456789。

  代码如下:

  

#include <stdlib.h>
#include <stdio.h>

int main(char *argv[], int argc)
{
    char *a = "abcd12345ed125ss123456789";
    int max = 1;
    int current_len = 1;
    int i = 0;
    int k = 0;
    char *outputptr = &a[0];
    int str_len = strlen(a);
    printf("%d\n",str_len);
    
    for(i=1; i<str_len;){
       if(a[i] == (a[i-1]+1)){
          current_len++;
          printf("%c,%c,%d\n",a[i],a[i-1],current_len);
            i++;
       }
         else {
          if(current_len > max){
               max = current_len;
               printf("ELSE:   current_len:%d ",current_len);
               outputptr = &a[i-max];
               printf("   current_Char:%c   STR:",outputptr[0]);
                  for(k = 0; k<max; k++){
                  printf("%c",outputptr[k]);
               }
               printf("\n"); 
          }
        current_len = 1;
        i++;
      }
    }
    if(current_len > max){
       max = current_len;          
       outputptr = &a[i-max];
    }
 
    printf("\n Len:%d\n",max);
    for(i = 0; i<max; i++){
       printf("%c",outputptr[i]);
    }
    printf("\n");
    system("PAUSE");
    return 0;
}
View Code

(5)、定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。

       算法描述:如果将字符串分为AB两部分,其中A表示要移动到字符串尾部的字符串,B表示剩余部分,我们先分别将A和B逆置,然后再将字符串作为一个

   整体来逆置,这样起到的效果是第一步先得到ATBT,然后得到(ATBT)T,即BA。 

   代码省略。

(6)、输入N个0,M个1,输出第K个组合。比如两个0,两个1.那么01的组合可以为:{0011,0101,0110,1001,1010,1100},那么第4个组合就是1001.

    输入为 N,M,K,输出第K个组合。

    代码如下:

#include <stdlib.h>
#include <stdio.h>


    int i = 0;
    int N = 3;  /*Number Of ZEROs*/
    int M = 2;  /*Number Of ONEs*/
    int step=0;  /*Kth   Seqence*/
    int Str_len = 5;
    int len;
    int Count_one = 0;
    char tmp='A';
    int k = 0;

    char A[5] = {'0','1','0','1','0'};
    
void move()
{
    Count_one = 0;
    len = Str_len-1;
    while(len>=0)
    {
       if(A[len] == '0') {
          len--;
       }
       if(A[len] == '1') {
          printf("IF\n");
          Count_one++;
          if(len == 0){
             printf("Final Format\n");
             break;
       }
       if(A[len-1] == '0' && Count_one<M) {
          printf("IF2\n");
          tmp = A[len];
          A[len] = A[len-1];
          A[len-1] = tmp;
          printf("A[len-1] == '0' && Count_one<M \n");
          for(i=0; i<Str_len; i++)
                printf("%c",A[i]);
          printf("\n");
          break;
        }
        if(A[len-1] == '0' && Count_one==M) {
          printf("IF3\n");
          tmp = A[len];
          A[len] = A[len-1];
          A[len-1] = tmp;
          for(k=len;k<Str_len;k++)
               A[k] = '0';
          for(k=0;k<M-1;k++)
               A[Str_len-k-1] = '1';
                     
          printf("A[len-1] == '0' && Count_one==M \n");
          for(i=0; i<Str_len; i++)
               printf("%c",A[i]);
          printf("\n");
               break;
        }
        if(A[len-1] == '1'){
           printf("A[len-1] == '1' \n");
           len--;
        }
     }
  }
}
    
int main(char *argv[], int argc)
{
    printf("\n");
    move();
    move();
    printf("\n");
    system("PAUSE");
    return 0;
}
View Code

 

(7)、For this question, your program is required to process an input string containing only ASCII characters between ‘0’ and ‘9’, or between

          ‘a’ and ‘z’ (including ‘0’, ‘9’, ‘a’, ‘z’).Your program should reorder and split all input string characters into multiple segments, and output

          all segments as one concatenated string. The following requirements should also be met,

          1. Characters in each segment should be in strictly increasing order. For ordering, ‘9’ is larger than ‘0’, ‘a’ is larger than ‘9’, and ‘z’ is

              larger than ‘a’ (basically following ASCII character order).

          2. Characters in the second segment must be the same as or a subset of the first segment; and every following segment must be the

              same as or a subset of its previous segment.

 

代码如下:

#include <stdio.h>
#include <stdlib.h>

struct ch_node
{
    char ch;
    int count;
};
int get_len(char *str)
{
    if(str == NULL)
       return 0;
    int i = 0;
    while(str[i] != '\0')
        i++;
    return i;
}
int Print(struct ch_node base[])
{
    int k = 0;
    int i = 0;
    while(k<36)
    {
      if(base[k].count>0){
         printf("%c",base[k].ch);
         base[k].count = base[k].count - 1;
         i++;
      }
      k++;
    }
    return i;
}
int main(char *argv[], int argc)
{
    //char *str_sequ = "007799aabbccddeeff113355zz";
    //char *str_sequ = "abcdefabcdefabcdefaaaaaaaaaaaaaabbbbbbbddddddee";
    char *str_sequ = "aabbccdd";
    
    char temp_ch = '0';
    
    int str_len = get_len(str_sequ);
    int i = 0;
    struct ch_node base[36];
    for (i=0; i<10 ;i++ ){
        base[i].ch = '0'+i;
        base[i].count = 0;
    }
    for (i=10; i<36; i++ ){
        base[i].ch = 'a'+(i-10);
        base[i].count = 0;
    }

    i = 0;
    while (i<str_len)
    {
        temp_ch = str_sequ[i];
        if(temp_ch >='0' && temp_ch <='9'){
           int temp_i = temp_ch - '0';
           base[temp_i].count = base[temp_i].count + 1;
        } else {
           int temp_i = temp_ch - 'a';
           base[temp_i+10].count = base[temp_i+10].count + 1;
        }
        i++;
    }
    
    printf("Result:");
    while(Print(base));
    printf("\n");
    
/*    for (i=0; i<36; i++ ){
        printf("%c--%d   ",base[i].ch,base[i].count);
        if(i>0 && i%6 == 0)
           printf("\n");
    }*/
    printf("\n");
    system("PAUSE");    
    return 0;
}
View Code

 


  




转载于:https://www.cnblogs.com/tju-gsp/p/3664762.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码下载:完整代码,可直接运行 ;运行版本:2022a或2019b或2014a;若运行有问题,可私信博主; **仿真咨询 1 各类智能优化算法改进及应用** 生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、解医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化 **2 机器学习和深度学习方面** 卷积神经网络(CNN)、LSTM、支持向量机(SVM)、最小乘支持向量机(LSSVM)、极限学习机(ELM)、核极限学习机(KELM)、BP、RBF、宽度学习、DBN、RF、RBF、DELM、XGBOOST、TCN实现风电预测、光伏预测、电池寿命预测、辐射源识别、交通流预测、负荷预测、股价预测、PM2.5浓度预测、电池健康状态预测、水体光学参数反演、NLOS信号识别、地铁停车精准预测、变压器故障诊断 **3 图像处理方面** 图像识别、图像分割、图像检测、图像隐藏、图像配准、图像拼接、图像融合、图像增强、图像压缩感知 **4 路径规划方面** 旅行商问题(TSP)、车辆路径问题(VRP、MVRP、CVRP、VRPTW等)、无人机三维路径规划、无人机协同、无人机编队、机器人路径规划、栅格地图路径规划、多式联运运输问题、车辆协同无人机路径规划、天线线性阵列分布优化、车间布局优化 **5 无人机应用方面** 无人机路径规划、无人机控制、无人机编队、无人机协同、无人机任务分配 **6 无线传感器定位及布局方面** 传感器部署优化、通信协议优化、路由优化、目标定位优化、Dv-Hop定位优化、Leach协议优化、WSN覆盖优化、组播优化、RSSI定位优化 **7 信号处理方面** 信号识别、信号加密、信号去噪、信号增强、雷达信号处理、信号水印嵌入提取、肌电信号、脑电信号、信号配时优化 **8 电力系统方面** 微电网优化、无功优化、配电网重构、储能配置 **9 元胞自动机方面** 交通流 人群疏散 病毒扩散 晶体生长 **10 雷达方面** 卡尔曼滤波跟踪、航迹关联、航迹融合

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值