【【萌新的c语言学习7】】

萌新的c语言学习7

//写一个函数可以逆序字符串的内容

void reverse(char* arr)
{
    assert(arr);
    int len = strlen(arr);
    char* left = arr;
    char* right = arr + len - 1;
    while (left <= right)
    {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
    
}

int main()
{
    int sz = 0;
    int i = 0;
    char arr[256] = { 0 };
    printf("请输入:");
    scanf("%s", arr);
    reverse(arr);
    printf("%s\n", arr);

    return 0;
}

//计算题

//算出s0=a+aa+aaa+aaaa+aaaaa前5项之和,其中a是数字
//例如a=2 ,那就是2+22+222+2222+22222
int main()
{
    int a = 0;
    int n = 0;
    scanf("%d%d", &a, &n);
    int sum = 0;
    int i = 0;
    int ret = 0;
    for (i = 0; i < n; i++)
    {
        ret = ret * 10 + a;
        sum += ret;
    }
    printf("%d", sum);
    return 0;
}

//打印水仙花数

//求出0~100000之内的所有水仙花数
// 水仙花数是一个n位数,是指各位数的n次方之和刚好等于该数本身,153=1^3+5^3+3^3 则153就是一个水仙花数
//
#include<math.h>
int main()
{
    int i = 0;
    int a = 0;
    for (i = 0; i <= 100000; i++)
    {
        int n = 1;
        //我们接下来需要先判断位数n
        //还有如何把i拆成各个数
        //最后进行比较
        int temp = i;
        while (temp/= 10)
        {
            n++;
        }
        //算到n位 再拆分 
        int sum = 0;
        int s = i;
        while (s )
        {
            a = s % 10;
            sum = sum+pow(s%10,n);
            s=s/ 10;
        }
        if (i == sum)
        {
            printf("水仙花数是:%d\n", i);
        }
    }
    return 0;
}
//我这么算最后都是0其实不对因为我们每次都在内部把i刷新成了0 所以最好用临时变量去做这些题

//打印一个菱形的图案

//13行
//               *               
//              ***     
//             *****
//              ***
//               * 
//就是类似这种的菱形 
//
int main()
{
    int line = 0;
    printf("请输入行数");
    scanf("%d", &line);
    //打印上半部分
    int i = 0;
    for (i = 0; i < line; i++)
    {
        int j = 0;
        for (j = 0; j < line - 1-i; j++)
        {
            printf(" ");
        }
        for (j = 0; j < 2*i+1; j++)
        {
            printf("*");
        }
        printf("\n");
    }
    //继续打印下半部分
    for (i = 0; i < line; i++)
    {
        int j = 0;
        for (j = 0; j < i; j++)
        {
            printf(" ");
        }
        for (j = 0; j < 2 * (line-1-i)-1; j++)
        {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

//汽水问题

//喝汽水 1瓶汽水 1元 2空瓶 换1瓶汽水给20 可以喝到多少汽水
int main()
{
    int money = 0;
    int total = 0;
    int empty = 0;
    printf("请输入多少钱:》");
    scanf("%d", &money);
    total = money;
    empty = money;
    while (empty / 2)
    {
        total = total + empty / 2;
        empty = empty / 2 + empty % 2;
    }
    printf("钱是:%d",total);
    return 0;
}
//自己想的,小学生做法是10块钱,买10瓶之后借10个空瓶,可以再换10瓶之后把瓶子还回去就是
//喝了2*10 =20瓶  在这里不允许借  所以 !!!!最终你都会剩下一瓶 
//所以答案是2*n-1    可以用这个原理验证是否作对

///调整奇数偶数的位置 使得奇数全部位于偶数的前面

// 输入一个整数数组实现一个函数
void move(int arr[], int sz)
{
    //我们先从前往后找到一个奇数
    //然后再找到一个偶数
    //然后把这两个数进行交换

    int left = 0;
    int right = sz - 1;
    while ((left<right)&&(arr[left] % 2 == 1))
    {
        left++;
    }
    while ((left < right)&&(arr[right] % 2 == 0))
    {
        right--;
    }
    if (left < right)
    {
        int temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
    }
}
void print(int arr[], int sz)
{
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}
int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };    
    int sz = sizeof(arr) / sizeof(arr[0]);
    move(arr,sz);
    print(arr, sz);
    return 0;
}

//字符串左旋

//什么意思就是左旋字符串中的k个字符
//例如ABCD 左旋 BCDA 
//例如ABCD  左旋 CDAB 
//旋转字符串
//可以完成左旋  也可以完成右旋
//
#include<string.h>
#include<assert.h>
void left_move(char arr[],int k)
{
    assert(arr);
    //因为最后面有一个\0所以我们的操作必须分段进行
    //首先我们先拿出首位元素放到临时变量里面
    // 然后把后面的元素移动一位
    // 再把a放到最后
    // 这就是完整的一次操作分成了3个步骤
    int i = 0;
    int len = strlen(arr);
    for (i = 0; i < k; i++)
    {
        //左旋转1个字符
        char temp = *arr;
        int j = 0;
        for (j = 0; j <len ; j++)
        {
            *(arr + j) = *(arr + j + 1);
        }
        *(arr + len - 1) = temp;
    }
}
int main()
{
    char arr[] = "abcdef";
    left_move(arr, 2);
    printf("%s\n", arr);
    return 0;
}

法一


法二

//上面的操作很复杂 接下来介绍一种简单的算法
//  首先有字符abcdef
// 切开 ab cdef 
// 然后先逆序一下变成 ba  fedc
// bafedc
// 反转一下
// cdefba

void reverse(char* left, char* right)
{
    assert(left != NULL);
    assert(right != NULL);
    while (left < right)
    {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}
void left_move(char arr[], int k)
{
    assert(arr);
    int len = strlen(arr);//求出字符串的长度
    assert(k <= len);
    reverse(arr, arr+k-1);//逆左边 需要知道逆序的头尾 
    reverse(arr+k,arr+len-1);//逆右边
    reverse(arr,arr+len-1);//完成对整体的逆序
}
int main()
{
    char arr[] = "abcdef";
    //其实就是在内部调用三次逆序方法
    left_move(arr, 4);
    printf("%s\n", arr);
    return 0;
}

void reverse(char* left, char* right)
{
    assert(left != NULL);
    assert(right != NULL);
    while (left < right)
    {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}
void left_move(char arr[], int k)
{
    assert(arr);
    int len = strlen(arr);//求出字符串的长度
    assert(k <= len);
    reverse(arr, arr+k-1);//逆左边 需要知道逆序的头尾 
    reverse(arr+k,arr+len-1);//逆右边
    reverse(arr,arr+len-1);//完成对整体的逆序
}
int is_left_move(char arr1[], char arr2[])
{
    int i = 0;
    int len = strlen(arr1);
    for (i = 0; i < len; i++)
    {
        left_move(arr1, 1);
        int ret = strcmp(arr1, arr2);
        if (ret == 0)
            return 1;
    }
    return 0;
}
int main()
{
    char arr1[] = "abcdef";
    char arr2[] = "cdefab";
    int ret= is_left_move(arr1, arr2);
    if (ret == 1)
    {
        printf("YES");
    }
    else
    {
        printf("NO");
    }
    return 0;
}

法一


法二:

//上述方法相对来说是穷举效率较低
//我们还有一种提升效率的方法
//就是我们给abcdef 后面再增加一个abcdef
// abcdefabcdef这样来说这个组合会包含所有存在的旋转后的组合
//
//
//
//
int is_left_move(char* arr1, char* arr2)
{
    //在arr1字符串后增加一个arr1字符串,然后判断
    // arr2指向的字符串是否是arr1字符串的子串
    //strcat(arr1, arr1);//strcat的用法
    //strcat自己给自己增加会出现问题
    int len1 = strlen(arr1);
    int len2 = strlen(arr2);
    if (len1 != len2)
        return 0;
     strncat(arr1,arr1,6);
     //strstr-找子串的
     char* ret = strstr(arr1, arr2);
     if (ret == NULL)
     {
         return 0;
     }
     else
     {
         return 1;
     }
    
}
int main()
{
    char arr1[30] = "abcdef";
    char arr2[] = "cdefab";
    int ret=is_left_move(arr1, arr2);
    if (ret == 1)
    {
        printf("YES\n");
    }
    else 
    {
        printf("NO \n");
    }
    return 0;
}

//杨氏矩阵

// 矩阵每行从左到右依次递增,从上到下也依次递增
// 编写程序判断某个数字在矩阵中是否存在
// 1 2 3
//4 5 6
// 7 8 9
//可
//1 2 3
//2 3 4
//4 5 6
//可

//找数为了节省时间
    //我们先从最后的出发 最后一个
    //比如说我们要找7 那么先拿第三列比较
    // 3 6 9 这样一下子就能去掉两个整行非常方便
    // 
    //
    //

int findnum(int arr[3][3],int k ,int row , int col )
{
    int x = 0;
    int y = col-1;
    while (x <= row - 1 && y >= 0)
    {
        if (arr[x][y] > k)
        {
            y--;
        }
        else if (arr[x][y] < k)
        {
            x++;
        }
        else
        {
            return 1;
        }
    }
    return 0;
}
int main()
{
    int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
    int k = 7;
    int ret = findnum(arr, k, 3, 3);
    if (ret == 1)
        printf("找到了");
    else
        printf("找不到");
    return 0;
}

//重新设计希望告诉我们变量在哪里

int findnum(int arr[3][3],int k ,int* row , int* col )
{
    int x = 0;
    int y = *col-1;
    while (x <= *row - 1 && y >= 0)
    {
        if (arr[x][y] > k)
        {
            y--;
        }
        else if (arr[x][y] < k)
        {
            x++;
        }
        else
        {
            *row = x;
            *col = y;
            return 1;
        }
    }
    return 0;
}
int main()
{
    int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
    int k = 7;
    int x = 3;
    int y = 3;
    int ret = findnum(arr, k, &x, &y);
    if (ret == 1)
        printf("找到了在%d %d ", x , y);
    else
        printf("找不到");
    return 0;
}
//传地址过去的形式
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值