数据结构之数组与字符串

一、数组

(题目与程序摘自《剑指offer》)

数组可以说是最简单的一种数据结构,它占用一块连续的内存并按照顺序存放。创建数组时我们需要知道数组的容量大小,然后根据大小分配内存。

由于不管有多少元素,数组都会为全部数据预算内存,所以空间效率不高;但是,由于数组中的内存是连续的,可以根据下标在O(1)时间读写任何元素,时间效率极高。

数组和指针是相互联系又相互关联,又有区别的两个概念。需要注意的是,使用指针访问数据库中的元素的时候,需要确保没有超出数组的边界。

例题:二维数组中的查找

void TestDemo()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    Test((int*)matrix, 4, 4, 7, true);
}
void Test(char* testName, int* matrix, int rows, int columns, int number, bool expected)
{
   Find(matrix, rows, columns, number);
}
bool Find(int* matrix, int rows, int columns, int number)
{
    bool found = false;

    if(matrix != NULL && rows > 0 && columns > 0)
    {
        int row = 0;
        int column = columns - 1;
        while(row < rows && column >=0)
        {
            if(matrix[row * columns + column] == number)
            {
                found = true;
                break;
            }
            else if(matrix[row * columns + column] > number)
                -- column;
            else
                ++ row;
        }
    }

    return found;
}

二、字符串

(题目与程序摘自《剑指offer》)

C/C++中每个字符串都以‘\0‘结尾,因此可以根据这个特点找见字符串的结尾,同样也会有额外的开销,所以需要注意字符串的越界问题。

为了节省内存,C/C++把常量字符串放在单独的一个内存区域。

char str1[]="hello world";
char str2[]="hello world";

char* str3="hello world";
char* str4="hello world";

str1和str2是两个字符串数组,并且是两个初始地址不同的数组,因此str1和str2的值也不相同。

str3和str4是两个指针,无须为它们分配内存以存放数据。str3和str4指向的是同一个地址。所以比较str3和str4的值得到的结果是相同的。

String str="hello";
str.ToUpper();
str.Insert(0," world");

以上虽然对str进行了操作,但是操作的结果都是在生成一个新的String实例并返回值中返回,str中的值本身不会发生变化。用String作连续修改,每一次修改都会产生一个临时对象,开销太大。因此在C#和Java中有StringBuilder,来容纳修改后的结果。

例题:替换空格

void ReplaceBlank(char string[], int length)
{
    if(string == NULL && length <= 0)
        return;

    /*originalLength 为字符串string的实际长度*/
    int originalLength = 0;
    int numberOfBlank = 0;
    int i = 0;
    while(string[i] != ‘\0‘)
    {
        ++ originalLength;

        if(string[i] == ‘ ‘)
            ++ numberOfBlank;

        ++ i;
    }

    /*newLength 为把空格替换成‘%20‘之后的长度*/
    int newLength = originalLength + numberOfBlank * 2;
    if(newLength > length)
        return;

    int indexOfOriginal = originalLength;
    int indexOfNew = newLength;
    while(indexOfOriginal >= 0 && indexOfNew > indexOfOriginal)
    {
        if(string[indexOfOriginal] == ‘ ‘)
        {
            string[indexOfNew --] = ‘0‘;
            string[indexOfNew --] = ‘2‘;
            string[indexOfNew --] = ‘%‘;
        }
        else
        {
            string[indexOfNew --] = string[indexOfOriginal];
        }

        -- indexOfOriginal;
    }
}

如果是合并两个数组时,从前往后复制需要移动多次,从后往前复制,这样就能减少移动的次数,从而提高效率。

时间: 2024-08-25 07:35:15

数据结构之数组与字符串的相关文章

剑指offer-第二章数据结构(数组,字符串,链表,树,栈与队列)及例题

一.数组(最简单的数据结构) 定义:占据一块连续内存并按照顺序存储数据.创建时先指定大小,分配内存. 优点:时间效率高.实现简单的hash(下标为key,对应的数据为value) 缺点:空间效率差.如果我们只在数组中存一个数字,也先分配所有的内存. 扩展:动态数组(解决空间效率差),手段:扩容后,复制内容到新的数组,释放之前的内存.时间性能变差,因此,要尽量减少改变数组容量的次数. 数组与指针:声明一个数组时,数组名字也是一个指针,指向数组的第一个元素. 例题:在一个二维数组中,每一行都按照从左

Swift 数组、字符串、集合与字典详解

今天我们来看几个最基本的数据结构:数组,字符串,集合和字典. 数组 数组是最基本的数据结构.Swift编程语言中改变了以前Objective-C时代NSMutableArray和NSArray分开的做法,统一到了Array唯一的数据结构.下面是最基本的一些实现. 1 2 3 4 5 6 7 8 9 10 11 // 声明一个不可修改的数组 let nums = [1, 2, 3] let nums = [Int](count: 5, repeatedValue: 0) // 声明一个可以修改的数

java常用的数组、字符串、集合操作以及数据结构与算法基本知识

java中常用封装的数组 .字符串. 集合来操作对象,但数据结构中常用的有栈和队列   数与图以及他们之间的排序,查找. 数组声明没有分配内存空间  只有创建或者是初始化时才分配,创建时把数组中的数据类型数据所在的内存空间首地址赋值给数组名,在创建每个对象时,都会给该对象分配地址和它存储的数据 .如变量    int arr[]; int arr[]={1,2,3};  arr=new int[10] ,int arr[][]={{1,9,7},{1,2,3}}  int arr[][]=new

[考研系列之数据结构]线性表之字符串

基本概念 串(字符串)  由0个或多个字符组成的有限序列,例如s="hello world" 串名  上例中的s 子串  某串任意连续字符组成的子序列,称为此字符串的子串 空串  0个字符的串,s="" 空格串  由一个或多个字符组成的串 模式匹配算法 作用 定位某子串T在字符串S中的位置 主串 S 模式串  T 针对模式匹配算法从简到难我们需要了解两种算法: [1] 朴素的模式匹配算法 [2] KMP匹配算法 朴素的模式匹配算法: 所谓朴素就是简单,这是一种简单的

程序员面试——数组与字符串

来自面试金典,只记录思路这些(博主最近时间紧,还是只像你仍代码吧... 1.1字符互异 思路一:双循环,O(n^2) import java.util.*; public class Different { public boolean checkDifferent(String iniString) { for (int i=0;i<iniString.length()-1;i++) { char tmp=iniString.charAt(i); for (int j=i+1;j<iniSt

【Cracking the Code Interview(5th edition)】一、数组与字符串(C++)

1.1 实现一个算法,确定一个字符串的所有字符是否全都不同.不允许使用额外的数据结构. 解答:这里假定字符集为ASCII码,可以与面试官沟通确认字符串使用的字符集.由于字符集是有限的,建立一个数组模拟的Hash表记录每个字符是否出现,线性扫描一次字符串即可,复杂度O(len(s)).如果字符集较大,需要考虑空间开销,则可以用bitset来实现. 1 bool isUnique(string s) { 2 bool record[256]; 3 memset(record, 0, sizeof(r

【Go】数组、字符串与切片

数组.字符串与切片 Go语言中数组.字符串和切片三者是密切相关的数据结构.这三种数据类型,在底层原始数据有着相同的内存结构.虽然数组的元素可以被修改,但是数组本身的赋值和函数传参都是以整体复制的方式处理的.字符串赋值只是复制了数据地址和对应的长度,而不会导致底层数据的复制. 数组 数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成.数组的长度是数组类型的组成部分.因为数组的长度是数组类型的一个部分,不同长度或不同类型的数据组成的数组都是不同的类型,因此在Go语言中很少

数组、字符串、集合

数组与集合的转换.数组与字符串的转换 ========数组变集合 String[] arr = {"abc","cc","kkkk"}; //把数组变成list集合有什么好处? /* 可以使用集合的思想和方法来操作数组中的元素. 注意:将数组变成集合,不可以使用集合的增删方法. 因为数组的长度是固定. contains. get indexOf() subList(); 如果你增删.那么会产生UnsupportedOperationExcepti

数组转字符串(属性加单引号,逗号分隔)

数组转字符串(属性加单引号,逗号分隔) 数组转字符串 PHP 应用场景:SQL写操作应用插入表字段值: 数组 $data $data = array('张三','男','20',''安徽省合肥市 '); 转换如下: #join $str = " ' " . join("','", array_values($data) ) . " ' "; #str_replace $str = " ' ".str_replace( &quo