数据结构、算法与编程(1)

这部分不会有很系统的讲解,只是列举一些题目,分享一下我和别人的思路。

1.1 数组的查找
数组,可以说是最简单的数据类型,它占用一块连续的内存并按照顺序存储数据。与vector不同,创建数组时,需要指定数组的大小,而且不允许动态增加数组元素。
数组中的内存是连续的,而且可以根据下标读写元素,时间效率高,正是这一点,我们可以使用它来实现简单的哈希表。
在C/C++中,数组和指针是互相关联,而又有区别的两个概念。当我们声明一个数组时,数组名同时也是一个指针,我们可以用指针访问数组。而两者的区别,我们可以使用sizeof()看出来:

#include <iostream>

using namespace std;

int GetSize(int data[])
{
    return sizeof(data);
}

int main()
{
    int data1[] = {1,2,3,4,5};
    int size1 = sizeof(data1);

    int *data2 = data1;
    int size2 = sizeof(data2);

    int size3 = GetSize(data1);
    cout << size1 << " " << size2 << " "<< size3;
}

运行结果:
这里写图片描述

sizeof(data1) - 求的是整个数组的大小;
sizeof(data2) - 求的是指针的大小,32位系统中为4;
GetSize(data3) - 函数调用用时,数组会自动退化为同类型的指针。

进入正题:二维数组中的查找

题目:(摘抄自剑指offer)
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路:不要使用逐个遍历,因为这个数组是有特点的,要利用数组本身的特点,进行计算。
举个实例:
这里写图片描述
如果寻找数字”1”,则返回true;如果寻找数字11,则返回false。

那么如何查找呢?
我们可以先查找最后的一列的第一行的元素,此处是4;如果target是小于该元素,则可略过该列,直接寻找它的前一列;如果target是大于该元素,则可以略过该行,直接寻找它的下一行。

程序实现:

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        /*二维数组的行数和列数*/
         int rowCount = array.size();  // 
         int colCount = array[0].size();

         int i, j;//i指定行的变化,j指定列的变化

         //循环
         for (i = 0, j = colCount-1; j>=0&&i<rowCount;)
         {
             if(target == array[i][j]) // 如果刚好等于target
                 return true;
             if(target < array[i][j]) // 如果target较小,则查找上一列
             {
                 --j;
                 continue;
             }
             if(target > array[i][j]) // 如果target较大,则查找下一行
             {
                 ++i;
                 continue;
             }
         }
         return false;
     }
};

同样用示例的数组作为实参,target设为1和11,运行得到结果:
这里写图片描述

运行成功,结果正确!

1.2 字符串的空格替换
在C/C++中,字符串都是以’\0’结尾的,这样我们很容易得到它的长度,当然,由于这个特性,我们在定义和使用字符串时,需要注意,不要造成字符串越界。

注意:为了节省内存,C/C++把常量字符串存放在独立的一个内存区域中,当指针赋值给相同的字符串时,它们实际上会指向相同的内存地址。

下面实例说明这一点
Exp:

#include <iostream>

using namespace std;

int main(int argv, char** argc)
{
    char s1[20] = "hello world";
    char s2[20] = "hello world";
    char *p = "hello world";
    char *q = "hello world";

    if(s1 == s2)
        cout << "s1 and s2 are the same!" << endl;  
    else
        cout << "s1 and s2 are not the same!" << endl;

    if(p==q)
        cout << "p and q are the same!" << endl;
    else
        cout << "p and q are not the same!" << endl;
}

运行结果:
这里写图片描述

s1和s2是两个字符串数组,在C/C++中,它们各自存放在不同的内存区域中,因此,输出的结果显示两者不同;
而p和q是两个指针,C/C++中无须为它们分配内存以及存储字符串的内容,而只需要把它们指向”hello world”在内存中的地址即可。而”hello world”是常量字符串,它在内存中只有一个拷贝,因此p和q指向的是同一个地址。所以,p和q得到的结果相同的。

替换空格

题目:请实现一个函数,把字符串中的每一个空格替换成"%20"。例如:输入"We Are Happy",则输出"We%20Are%20Happy"。

分析:
与实际结合,在网络编程中,当URL参数中含有特殊字符,如空格、#号等,可能导致服务器无法获取正确的参数值。我们需要将这些特殊字符转换成服务器能识别的字符。

就本题而言,通过直接遍历,复制一个新的数组,这个是从前到后改变数组的值,可以实现该题功能,但是这样实现很复杂。

新思路:从后改变数组的值。先遍历求出数组的实际长度,并且求出新数组的实际长度,然后,使用下标从后给新数组赋值。如下图所示:
这里写图片描述

这样,就不需要两次遍历整个数组。

代码实现:

#include<stdio.h>

class Solution
{
public:
    void replaceSpace(char *str, int length)
    {
        // 简单的错误性判断
        if(*str==NULL && length <= 0)
            return ;
        // 首先计算原始数组长度,统计空格的个数
        int OldLength = 0;
        int i = 0;
        int BlankNum = 0;
        while(str[i] != '\0') // 字符串数组可以使用该特点
        {
            if(str[i] == ' ')
                ++ BlankNum;
            ++ i;
            ++ OldLength; // 注意:此处不能使用i作为数组长度,因为最后一个i对应的是'\0'
        }
        // 求出新数组的长度
        // 并使用下表从尾到头进行赋值
        int Oldindex = OldLength;
        int Newindex = OldLength + 2*BlankNum;
        while(Oldindex <= Newindex && Oldindex>=0)
        {
            if(str[Oldindex]==' ')
            {
                str[Newindex--] = '0';
                str[Newindex--] = '2';
                str[Newindex--] = '%';
            }
            else
            {
                str[Newindex--] = str[Oldindex];
            }
            --Oldindex;
        }
    }
};

int main()
{ 
    char str11[20] = "We Are Happy";  // 注意:此处应该给出合理的大小,虽然也会有结果,
                                    // 但是同时也会产生调试错误!
    char *q = str11;
    printf("Original char array: \n");
    while(*q != '\0')
    {
        printf("%c",*q);
        q++;
    }
    printf("\n\n");

    Solution s1;
    s1.replaceSpace(str11,50);
    char *p = str11;

    printf("After solution: \n");
    while(*p != '\0')
    {
        printf("%c",*p);
        p++;
    }
    printf("\n");
    return 0;
}

运行结果:
这里写图片描述

运行成功!

猜你喜欢

转载自blog.csdn.net/louishao/article/details/77970208