1. 程式人生 > >文章標題 c語言中關於串的相關知識以及操作

文章標題 c語言中關於串的相關知識以及操作

1)串的基本概念

串,即是字串,由零個或者多個字元組成的有限序列,是資料元素為單個字元的特殊線性表。一般記為:S1='a1a2a3a4a5....an'。

2)串的儲存結構:

定長順序儲存結構、堆分配儲存結構和塊鏈儲存結構三種。

  a.*定長順序儲存結構*
   定長順序儲存結構是用一組地址連續的儲存單元儲存串值的字元序列,就是將串定義成字串陣列。陣列的名字就是串名。陣列的上界預先給出,所以也稱為靜態儲存。

儲存結構定義如下:       
     #define MAXL 256
     typedef unsigned char SString[MAXL+1];//0號單元用於儲存串長,串值從1號單元開始放。
     另一種是從0號單元開始儲存串值。結構定義如下:
     #define MAXL 60
     typedef struct
     {
     char str[MAXL];
     int length;
     }SString;
此種儲存結構有來兩個缺點:
一是需要預先定義一個串允許的最大長度,當MAXL估計過大的時候串的儲存密度就會降低,會浪費較多空間;二是由於限定了串的最大長度,使串的某些運算,比如聯接收到一定限制。

 b.*堆分配儲存結構儲存*
  它其實也是利用一組地址連續的儲存單元儲存串值的字元序列,但是儲存空間是在程式執行的時候動態分配的。因此可以利用c語言中動態分配函式庫中的malloc()來分配空間,還可以利用realloc()增加空間

  儲存結構定義如下:
  typedef struct
  {
    char *ch;
    int length;
  }HString;

c.*塊鏈儲存結構*
是使用鏈式存數結構儲存串,每個節點有data域和next指標域組成。

  #define CHUNKSIZE 80
  typedef struct Chunk
  {
  char ch[CHUNKSIZE];
  struct CHunk *next;
  }Chunk;
  typedef struct
  {
  Chunk *head,*tail;
  int curlen;
  }LString;

3)串的相關操作:

   1.串賦值演算法: 
#include<stdio.h>
#define MAXL 256
typedef unsigned char str[MAXL];

void strAssign(str &T, char *chars)
{
    int i = 0;
    T[0] = 0;//0號單元儲存字串長度
    for ( i = 0; chars[i]; i++)
    {
        T[i + 1] = chars[i];//用字元陣列chars給串賦值.
    }
    T[0] = i;
}

void main()
{
    str T;
    char
chars[] = "abcdefghijk"; strAssign(T, chars); printf("串長是%d\n ", T[0]); printf("賦值後的串是 :"); for (int i = 1; i <= T[0]; i++) { printf("%c", T[i]); } }
2.求子串演算法:
    #include<stdio.h>
#define MAXL 256
#define ERROR 0
#define OK 1

typedef int Status;
typedef unsigned char str[MAXL];

void strAssign(str &T, char *s
) //用字元陣列給T賦值 { int i = 0; T[0] = 0; for (; s[i]; i++) T[i + 1] = s[i]; T[0] = i; } Status subString(str &sub, str T, int pos, int len) //用sub返回第 pos個字元起長度為len的子串。 { if (pos<1 || pos>T[0] || len<0 || len>T[0] - pos + 1) return ERROR; for (int i = 1; i <= len; i++) { sub[i] = T[pos + i - 1]; } sub[0] = len; } void main() { int pos, len; str T, sub; char chars[100]; printf("請輸入字串 "); //scanf_s("%[^\n]", chars, sizeof(chars));//[^\n]只有遇到回車才會停止讀入. gets_s(chars);//此處若是使用scanf_s()如上面註釋的那樣,也是沒問題的. strAssign(T, chars); printf("請輸入子串開始的位置和長度(中間用逗號隔開) "); scanf_s("%d,%d", &pos, &len); getchar(); if (subString(sub, T, pos, len))//判斷是否取子串成功. { printf("從第%d位置開始,長度為%d的子串為 ", pos, len); for (int i = 1; i <= sub[0]; i++) { printf("%c", sub[i]); } printf("\n"); } else printf("求子串失敗.....\n"); }
  3.串比較演算法:
#include<stdio.h>
#include<stdlib.h>

#define OK 1
#define ERROR 0
#define OVERFLOW -1

typedef int Status;
//串的堆分配儲存表示
typedef struct
{
    char *ch;
    int length;
}HString;

Status strAssign(HString &s, char *chars)
{
    int i;
    char *c = chars;
    for (i = 0; *c; i++, c++);//求chars的長度
    if (!i)
    {
        s.ch = NULL;
        s.length = 0;
    }
    else
    {
        s.ch = (char*)malloc(i*sizeof(char));
        if (!(s.ch))exit(OVERFLOW);
        for (int j = 0; j < i; j++)
        {
            s.ch[j] = chars[j];
        }
        s.length = i;
    }
    return OK;
}

Status strCompareTo(HString a, HString b)
//若a<b,則則返回值<0,若a>b,則返回值>0,若a=b,則返回值=0;
{
    int i = 0;
    for (int i = 0; i < a.length&&b.length; i++)
    {
        if (a.ch[i] != b.ch[i])
            return (a.ch[i] - b.ch[i]);
    }
    return (a.length - b.length);
}

void main()
{
    HString Sa, Sb;
    char char_a[100], char_b[100];
    printf("請輸入字串a:");
    gets_s(char_a);
    strAssign(Sa, char_a);
    printf("請輸入字串b:");
    gets_s(char_b);
    strAssign(Sb, char_b);
    if (strCompareTo(Sa, Sb) == 0)
        printf("串 %s 等於串 %s", char_a, char_b);//此處是char_a,char_b,不能是Sa,Sb.
    if (strCompareTo(Sa, Sb) < 0)
        printf("串 %s 小於串 %s", char_a,char_b);
    if (strCompareTo(Sa, Sb)>0)
        printf("串 %s 等於串 %s", char_a, char_b);

}
4.串聯接演算法
#include <stdio.h>

#define TRUE 1
#define FALSE 0
#define MAXL 255

typedef int Status;
typedef unsigned char SString[MAXL + 1];

void strAssign(SString &T, char *s)
//用字元陣列s給串T賦值
{
    T[0] = 0;
    int i = 0;
    for (; s[i]; i++)
    {
        T[i + 1] = s[i];
    }
    T[0] = i;
}

//定義了一個int型變數uncut,用於判斷是否會被截斷。
//uncun = TRUE時未被截斷,uncut=FALSE時被截斷。
Status connect(SString &T, SString S1, SString S2)
{
    int uncut, i;
    if (S1[0] + S2[0] <= MAXL)//未截斷,注意0號單元儲存的是串長.
    {
        for (i = 1; i <= S1[0]; i++)
            T[i] = S1[i];
        for (i = 1; i < S2[0]; i++)
            T[S1[0] + i] = S2[i];
        T[0] = S1[0] + S2[0];
        uncut = TRUE;
    }

    else if (S1[0] < MAXL)//S2被截斷
    {
        for (i = 1; i <= S1[0]; i++)
            T[i] = S1[i];
        for (i = 1; i <= MAXL - S1[0]; i++)//注意此時的迴圈條件.
            T[S1[0] + i] = S2[i];
        T[0] = MAXL;
        uncut = FALSE;
    }

    else//S1,S2均被截斷。
    {
        for (i = 1; i <= MAXL; i++)
            T[i] = S1[i];
        uncut = FALSE;
    }
    return uncut;
}

void main()
{
    SString S1, S2, T;
    char char_s1[100], char_s2[100];
    printf("請輸入字串S1:");
    gets_s(char_s1);
    printf("請輸入字串S2:");
    gets_s(char_s2);

    strAssign(S1, char_s1);
    strAssign(S2, char_s2);

    if (connect(T, S1, S2))
    {
        printf("S1= %s 和 S2= %s 聯接過程中未被截斷,連線後的串是: ", char_s1, char_s2);
        for (int i = 1; i <= T[0]; i++)
            printf("%c", T[i]);
    }
    else
    {
        printf("S1= %s 和 S2= %s 聯接過程中被截斷,連線後的串是: ", char_s1, char_s2);
        for (int i = 1; i <= T[0]; i++)
            printf("%c", T[i]);
    }
}
5.串的模式匹配演算法
#include<stdio.h>

#define MAXL 255
#define OK 1
#define OVERFLOW -1


typedef unsigned char SString[MAXL+1];

void strAssign(SString &T, char *s)
//用字元陣列s給串T賦值.
{
    int i = 0;
    T[0] = 0;//0號單元儲存串長.
    for (; s[i]; i++)
    {
        T[i + 1] = s[i];
    }
    T[0] = i;
}

int index(SString T, SString S, int pos)
//返回子串S在主串T第pos個字元開始匹配的位置,若不存在,則返回0;
{
    int i = pos,j=1;
    while (i <= T[0] && j <= S[0])
    {
        if (T[i] == S[j])
        {
            i++;
            j++;
        }
        else
        {
            i = i - j + 2;
            j = 1;
        }
    }
    if (j > S[0])
        return i - S[0];
    else
        return 0;
}

void main()
{
    int pos;
    SString T, S;
    char char_a[100], char_b[100];
    printf("請輸入主串A:");
    gets_s(char_a);
    printf("%s\n", char_a);
    printf("請輸入主串B:");
    gets_s(char_b);
    printf("%s\n", char_b);

    strAssign(T, char_a);
    strAssign(S, char_b);

    printf("賦值成功!\n");

    pos = index(T, S, 1);
    if (pos)
    {
        printf("主串 T=%s 的子串 S=%s 在第%d個位置開始匹配。",char_a,char_b,pos);
    }
    else
        printf("主串 T=%s 和子串 S=%s 不匹配",char_a,char_b);
}

以上就是串相關知識以及一些簡單操作,程式碼處理平臺是vs2013。初來乍到,多多關照,有什麼寫的不對的,歡迎指正。