算法与数据结构复习基本代码(一)

  • 线性表
    • 线性表
    • 顺序表
    • 单链表
    • 双链表
    • 顺序栈
    • 链式栈
    • 表达式求值
  • 队列
    • 顺序队列
    • 链式队列
  • 字符串

线性表

线性表

  • 线性表的抽象数据类型定义
template <class T>
class List {void clear();   //置空线性表bool isEmpty();  //线性表为空时,返回truebool append(const T value);   //在表尾添加一个元素value,表的长度增1bool insert(const int p, const T value);//在位置p上插入一个元素value,表的长度增1bool delete(const int p);        //删除位置p上的元素,表的长度减1bool getValue(const int p, T& value);  //把位置p的元素值返回到变量value中bool setValue(const int p, const T value); //用value修改位置p的元素值bool getPos(int& p, const T value);    //把值为value的元素所在的位置返回到变量p中
};

线性表的存储结构主要有两类

  1. 定长的顺序存储结构,简称顺序表。程序中通过创建数组来建立这种存储结构
  2. 变长的线性存储结构,也称链接式存储结构,简称链表。

顺序表

按顺序方式存储的线性表称为顺序表(array - based list),又称为向量,通过创建数组来建立。顺序表中的每个元素按其顺序有唯一的索引值,又称下标值,可以用来方便地访问元素内容。

一种顺序表的类定义

template<class T>              //假定顺序表的元素类型为T
class arrList :public List<T> {   //顺序表,向量
private:                        //线性表的取值类型和取值空间T* aList;                    //私有变量,存储顺序表的实例int maxSize;              //私有变量,顺序表实例的最大长度int curLen;                 //私有变量,顺序表实例的当前长度int position;               //私有变量,当前处理位置
public:                         //顺序表的运算集arrList(const int size) {  //创建一个新的顺序表,参数为表实例的最大长度maxSize = size;aList = new T[maxSize];curLen = position = 0;}~arrList() {             //析构函数,用于消除该表实例delete[] aList;           }void clear() {             //将顺序表存储的内容清除,成为空表delete[] aList;curLen = position = 0;aList new T[maxSize];}int length();         //返回此顺序表的当前实际长度bool append(const T value);  //在表尾添加一个元素value,表的长度增1bool insert(const int p, const T value);//在位置p上插入一个元素value,表的长度增1bool delete(const int p);   //删除位置p上的元素,表的长度减1bool setValue(const int p, const T value); //用value修改位置p的元素值bool getValue(const int p, T& value);  //把位置p的元素值返回到变量value中bool getPos(int& p, cosnt T value);    //查找值为value的元素,并返回第1次出现的位置
};

顺序表的运算实现

  • 顺序表的检索
//在表中查找值为value的元素
//成功则返回true,并将该元素所在的下标记录在参数p中,失败则返回false
template <class T>
bool arrList<T>::getPos(int& p, const T value) {int i;        //元素下标for(i=0;i<n;i++)    //依次比较if (value == aList[i]) {//下标为i的元素与value相等p = i;        //将下标由参数p返回return true;}return false;       //顺序表没有元素值为value的元素
}
  • 顺序表的插入
//设元素的类型为T,aList是存储顺序表的数组,maxSize是其最大长度;
//p为新元素value的插入位置,插入成功返回true,否则返回false
template<class T>     //假定顺序表的元素类型为T
bool arrList<T>::insert(const int p, const T value) {int i;if (curLen >= maxSize) {//检查顺序表是否溢出cout << "The list is overflow" << endl;return false;}if (p<0 || p>curLen) {//检查插入位置是否合法cout << "Insertion point is illegal" << endl;return false;}for (i = curLen; i > p; i--)aList[i] = aList[i - 1];   //从表尾curLen-1起向右移动直到paList[p] = value;     //位置p处插入新元素curLen++;      //表的实际长度增1return true;
}
  • 顺序表的删除
//设元素的类型为T,aList是存储顺序表的数组;p为即将删除元素的位置
//删除成功则返回true,否则返回false
template<class T>     //顺序表的元素类型为T
bool arrList<T>::delete(const int p) {int i;if (curLen <= 0) {    //检查顺序表是否为空cout << " No element to delete \n" << endl;return false;}if (p<0 || p>curLen - 1) {//检查删除位置是否合法cout << " deletion is illegal\n" << endl;return false;}for (i = p; i < curLen - 1; i++)aList[i] = aList[i + 1]; //从位置p开始每个元素左移直到curLencurLen--;     //表的实际长度减1return true;
}

单链表

单链表的结点定义

template <class T>class Link {public: T data;     //用于保存结点元素的内容Link<T>* next;   //指向后继结点的指针Link(const T info, const Link<T>* nextValue = NULL) {//具有两个参数的Link构造函数data = info;next = nextValue;}Link(const Link<T>* nextValue) {//具有一个参数的Link构造函数next = nextValue;}
};

单链表的类型定义

template<class T> class lnkList :public List<T> {private:Link<T>* head, * tail;    //单链表的头尾指针Link<T>* setPos(const int p);//返回线性表指向第p个元素的指针值
public:lnkList(int s);  //构造函数~lnkList();       //析构函数bool isEmpty();//判断链表是否为空void clear();    //判断链表是否为空int length(); //返回此链表的当前实际长度bool append(const T value);//在表尾添加一个元素value,表的长度增1bool insert(const int p, const T value);//在位置p上插入一个元素value,表的长度增1bool delete(const int p);    //删除位置p上的元素,表的长度减1bool getValue(const int p, T& value);//返回位置p的元素值bool getPos(int& p, const T value);//查找值为value的元素,并返回第一次出现的位置
};

带有头结点的单链表构造函数与析构函数

template <class T>
lnkList::lnkList(int defSize) {head = tail = new Link<T>;//此处采用class Link的构造函数来初始化head和tail
}
template<class T>
lnkList::~LnkList() {Link<T>* tmp;while (head != NULL) {tmp = head;head = head->next;delete tmp;}
}

链表的检索

//寻找链表的第i个结点
template<class T> //线性表的元素类型为T
Link<T>* lnkList<T>::setPos(int i) {int count = 0;if (i == -1)   //i为-1则定位到头结点return head;Link<T>* p = new Link<T>(head->next);//循链定位,若i为0则定位到第一个结点while (p != NULL && count < i) {p = p->next;count++;}return p;//指向第i结点,i=0,1,...,当链表中结点数小于i时返回NULL
}

链表的插入和删除

template <class T>
bool lnkList<T>::insert(const int i, const T value) {Link<T>* p, * q;if ((p = setPos(i - 1)) == NULL) {//p是第i个结点的前驱cout << "非法插入点" << endl;return false;}q = new Link<T>(value, p->next);p->next = q;if (p == tail)        //插入点在链尾,插入结点成为新的链尾tail = q;return true;
}

单链表的删除算法

template<class T>
bool lnkList<T>::delete(const int i) {Link<T>* p, * q;if((p=setPos(i-1))==NULL||p==tail){//待删结点不存在,即给定的i大于当前链中元素个数cout << "非法删除点" << endl;return false;}q = p->next;      //q是真正待删结点if (q == tail) {//待删结点为尾结点,则修改尾指针tail = p;p->next = NULL;delete q;}else if(q!=NULL){//删除结点q并修改链指针p->next = q->next;delete q;}return true;
}

双链表

双链表的结点定义和实现。

template<class T>class Link {public:T data;  //用于保存结点元素的内容Link<T>* next;//指向后继结点的指针Link<T>* prev;//指向前驱结点的指针Link(const T info, Link<T>* preValue = NULL, Link<T>* nextValue = NULL) {//构造函数,值和前后指针data = info;next = nextValue;prev = preValue;}Link(Link<T>* preValue = NULL, Link<T>* nextValue = NULL) {//给定前后指针的构造函数next = nextValue;prev = preValue;}
}

如果要删除指针变量p所指的结点,需要通过下述的操作来维护前驱和后继两条链:
p->prev->next=p->next;
p->next->prev=p->prev;
然后把变量p的前驱和后继置空,再释放p所指的空间即可:
p->next=NULL;
p->prev=NULL;
delete p;

同样,双链表中要在p所指结点后插入一个新结点q,具体操作步骤如下:

  1. 执行new q开辟结点空间。

  2. 填写新结点的数据域信息。

  3. 填写新结点在链表中的链接关系,即
    q->prev=p;
    q->next=p->next;

  4. 修改p所指结点及其后继结点在新结点插入后的链接信息,即把新结点的地址填入原p所指结点的next域以及新结点后继的prev域回指新结点本身,即
    p->next=q;
    q->next->prev=q;

无论是往栈中插入元素还是删除栈中的元素,或者读取栈中的元素,都只能固定在线性表的一段进行。通常,栈的这一端被称为栈顶(top)
与此相对,栈的另一端叫做栈底(bottom)
栈被称为后进先出(last in first out)表,简称LIFO表
进栈push、出栈pop、读栈顶top

栈的抽象数据类型定义:

template<class T>
class Stack {public:     //栈的运算集void clear();    //变为空栈bool push(const T item);  //item入栈,成功则范湖真,否则返回假bool pop(T& item);       //返回栈顶内容并弹出,成功返回真,否则返回假bool top(T& item);     //返回栈顶内容但不弹出,成功返回真,否则返回假bool isEmpty();       //若栈已空返回真bool isFull();     //若栈已满返回真
};

顺序栈

栈的顺序实现

template<class T>
class arrStack :public Stack<T> {private:        //栈的顺序存储int mSize;  //栈中最多可存放的元素个数int top;  //栈顶位置,应小于mSizeT* st;        //存放栈元素的数组
public:arrStack(int size) {//创建一个给定长度的顺序栈实例mSize = size;top = -1;st = new T[mSize];}arrStack() {//创建一个顺序栈实例top = -1;}~arrStack() {//析构函数delete[]st;}void clear() {//清空栈内容top = -1;}bool push(const T item) {//入栈操作的顺序实现if (top == mSize - 1) {//栈已满cout << "栈满溢出" << endl;return false;}else {     //新元素入栈并修改栈顶指针st[++top] = item;return true;}}bool pop(T& item) {//出栈顺序实现if(top==-1){//栈为空cout << "栈为空,不能执行出栈操作" << endl;return false;}else {item = st[top--];//返回栈顶元素并修改栈顶指针return true;}}bool top(T& item) {//返回栈顶内容,但不弹出if (top == -1) {cout << "栈为空,不能读取栈顶元素" << endl;return false;}else {item = st[top];return true;}}
};

改进的进栈操作

template<class T>
bool arrStack<T>::push(const T item) {if (top == mSize - 1) {T* newSt = new T[mSize * 2];for (i = 0; i <= top; i++)newSt[i] = st[i];delete[]st;    //释放原栈st = newSt;mSize *= 2;}st[++top] = item;return true;
}

链式栈

链表的结点类型采用前面已定义过的Link类模板。进栈操作push在链表头插入元素,出栈操作pop删除链头元素并释放空间。

栈的链式实现:

template<class T>
class lnkStack :public Stack<T> {private:        //栈的链式存储Link<T>* top; //指向栈顶的指针int size;      //存放元素的个数
public:         //栈运算的链式实现lnkStack(int defSize) {//构造函数top = NULL;size = 0;}~lnkStack() { //析构函数clear();}void clear() {//清空栈内容while (top != NULL) {Link<T>* tmp = top;top = top->next;delete tmp;}size = 0;}bool push(const T item) {//入栈操作的链式实现Link<T>* tmp = new Link<T>(item, top);top = tmp;size++;return true;}bool pop(T& item) {//出栈的链式实现Link<T>* tmp;if (size == 0) {cout << "栈为空,不能执行出栈操作" << endl;return false;}item = top->data;tmp = top->next;delete top;top = tmp;size--;return true;}bool top(T& item) {//返回栈顶内容但不弹出if (size == 0) {cout << "栈为空,不能读取栈顶元素" << endl;return false;}item = top->data;return true;}
};

表达式求值

后缀表达式求值

//Class Declaration类的说明
class Calculator {private:Stack<double>s;       //此栈用于压入保存操作数bool GetTwoOperands(double& opd1, double& opd2);//从栈顶弹出两个操作数opd1和opd2void Compute(char op);    //取两个操作数并按op对两个操作数进行计算
public:Calculator(void) {}; //创建计算器示例,开辟一个空栈void Run(void);      //读入后缀表达式,遇到符号"="时求值运算结束void Clear(void); //计算器的清除,为下一次计算做准备
};
//计算器类class Calculator中部分成员函数的程序实现
bool Calculator::GetTwoOperands(double& opd1, double& opd2) {if (s.isEmpty()) {cerr << "Missing operand!" << endl;return false;}s.pop(&opd1); //右操作数if (s.isEmpty()) {cerr << "Missing operand!" << endl;return false;}s.pop(&opd2);    //左操作数return true;
}
//调用GetTwoOperands,并按op运算对两个操作数进行计算
void Calculator::Compute(char op) {bool result;double operand1, operand2;result = GetTwoOperands(operand1, operand2);//从栈中连续弹出两个操作数if (result == ture)   //根据操作符对操作数进行运算switch (op) {case'+':s.push(operand2 + operand1); break;case'-':s.push(operand2 - operand1); break;case'*':s.push(operand2 * operand1); break;case'/':if (operand1 == 0.0) {cerr << "Divide by 0!" << endl;s.clear();}elses.push(operand2 / operand1);break;}elses.clear();
}
//读入表达式,遇到操作数则入栈,遇到操作符则从栈中连续弹出两个操作数计算,遇“=”结束
void Calculator::Run(void) {char c;double newOperand, res;while (cin >> c, c != '=') {//根据输入数据进行判断switch (c) {case'+':case'-':case'*':case'/':Compute(c);    //遇到操作符调用Compute计算break;default://遇到操作数则入栈cin.putback(c);cin >> newOperand;s.push(newOperand);break;}}if (s.pop(&res))cout << res << endl;    //打印出求值的最后结果
}

队列

按照习惯,通常会把只允许删除的一端称为队列的头,简称队头(front),把删除操作本身称为出队(dequeue);而称表的另一端为队列的尾,简称队尾(rear),这一端只能进行插入操作,称为入队(enqueue)。
队列通常也被称为先进先出(first in first out)表,简称FIFO表

队列的抽象数据类型定义:

template<class T>
class Queue {public: //队列的运算集void clear();   //变成空队列bool enQueue(const T item);  //将item插入队尾,成功则返回真,否则返回假bool deQueue(T& item);    //返回队头元素并将其从队列中删除,成功则返回真bool getFront(T& item);  //返回队头元素,但不删除,成功则返回真bool isEmpty();   //返回真,若队列已空bool isFull();    //返回真,若队列已满
};

顺序队列

队列的顺序实现

template<class T>
class arrQueue :public Queue<T> {private:int mSize;  //存放队列的数组的大小int front;  //表示队头所在位置的下标int rear;  //表示队尾所在位置的下标T* qu;     //存放类型为T的队列元素的数组
public:arrQueue(int size) {//创建队列的实例mSize = size + 1; //浪费一个存储空间,以区别队列空和队列满qu = new T[mSize];front = rear = 0;}~arrQueue() {//消除该实例,并释放其空间delete[]qu;}void clear() {//清空队列front = rear;}bool enQueue(const T item) {//item入队,插入队尾if (((rear + 1) % mSize) == front) {cout << "队列已满,溢出" << endl;return false;}qu[rear] = item;rear = (rear + 1) % mSize;   //循环后继return true;}bool deQueue(T& item) {//返回队头元素并从队列中删除if (front == rear) {cout << "队列为空" << endl;return false;}item = qu[front];front = (front + 1) % mSize;return true;}bool getFront(T& item) {//返回队头元素,但不删除if (front == rear) {cout << "队列为空" << endl;return false;}item = qu[front];return true;}
};

链式队列

队列的链式实现

template<class T>
class lnkQueue :public Queue<T> {private:int size;       //队列中当前元素个数Link<T>* front;    //表示队头的指针Link<T>* rear;   //表示队尾的指针
public:lnkQueue(int size) {//创建队列的实例size = 0;front = rear = NULL;}~lnkQueue() {//消除该实例,并释放其空间clear();}void clear() {//清空队列while (front != NULL) {rear = front;front = front->next;delete rear;}rear = NULL;size = 0;}bool enQueue(const T item) {//item入队,插入队尾if (rear == NULL) {//空队列front = rear = new Link<T>(item, NULL);}else {//添加新的元素rear->next = new Link<T>(item, NULL);rear = rear->next;}size++;return true;}bool deQueue(T& item) {//返回队头元素并从队列中删除Link<T>* tmp;if (size == 0) {//队列为空,没有元素克出队cout << "队列为空" << endl;return false;}&item = front->data;tmp = front;front = front->next;delete tmp;if (front == NULL)rear = NULL;size--;return true;}bool getFront(T& item) {//返回队头元素,但不删除if (size == 0) {//队列为空,无法获取队头cout << "队列为空" << endl;return false;}item = front->data;return true;}
};

字符串

<string.h>常用函数总结

标准库<string.h>提供了若干处理字符串的常用函数。

函数 说明
char *strcat(char *s1, const char *s2); 该函数把s2指向的字符串拷贝至s1指向的字符串末尾。S2字符串的第一个字符将覆盖s1字符串末尾的空字符。该函数返回s1.
char *strncpy(char * s1,const char *s2,size_t n); 该函数把s2指向的字符串拷贝至s1指向的位置,拷贝的字符数不超过n,其返回值是s1。该函数不会拷贝空字符后面的字符,如果源字符串的字符少于n个,目标字符串就以拷贝的空字符结尾;如果源字符串有n个或超过n个字符,就不拷贝空字符。
char *strncat(char *s1,const char *s2,int n); 该函数把s2字符串中的n个字符拷贝至s1字符串末尾。s2字符串的第一个字符将覆盖s1字符串末尾的空字符。不会拷贝s2字符串中的空字符和其后的字符,并在拷贝字符的末尾添加一个空字符。该函数返回s1
char *strcmp(const char *s1,const char *s2); 如果s1字符串在机器排序序列中位于s2字符串的后面,该函数返回一个正数;如果两个字符串相等,则返回0;如果s1字符串在机器排序序列中位于s2字符串的前面,则返回一个负数。
char*strncmp(const char s1,const chars2,int n); 该函数的作用和strcmp()类似,不同的是,该函数在比较n个字符后遇到第一个空字符时停止比较
char*strchr(const char *s,int c); 如果s字符串中包括c字符,该函数返回指向s字符串首次输出的c字符的指针;如果未找到,则返回空指针。
char* strpbrk(const char*s1,const char *s2); 如果s1中包含s2字符串中的任意字符,该函数返回指向s1字符串首位置的指针。如果未找到,则返回空字符。
char *strrchr(const char *s,int c); 该函数返回s中c字符的最后一次出现的位置(末尾的空字符也是字符串的一部分,所以在查找范围内)如果未找到,返回空指针。
char *strstr(const char *s1,const char *s2); 该函数返回指向s1中s2出现的首位置。如果在s1中没有找到s2,则返回空指针。
size_t strlen(const char *s); 返回s中的字符数,不包括末尾的空字符。

< string>常用函数用法总结

string str ; //生成空字符串
string s(str) ; //拷贝构造函数
string s ( str, strbegin, strlen ) ;//将字符串str中从下表strbegin开始,长度为strlen的部分作为字符串初值。
string s (cstr, char_len);//以C_string类型cstr的前char_len个字符作为s的初值
string s (num, c);//生成num个c字符的字符串
string s (str, stridx ); //将字符串str中从下标stridx开始到字符串结束的位置作为字符串初值

string str1; //生成空字符串
string str2("123456789");//生成"123456789"的复制品
string str3("12345",0,3);//结果为“123”
string str4("012345",5);//结果为"01234"
string str5(5,'1');   //结果为“11111”
string str6(str2,2);//结果为“3456789”

string的大小和容量:

  1. size()和length():返回string对象的字符个数,他们执行效果相同。

  2. max_size():返回string对象最多包含的字符数,超出会抛出length_error异常

  3. capacity():重新分配内存之前,string对象能包含的最大字符数

void test2()
{string s("1234567");cout << "size=" << s.size() << endl;cout << "length=" << s.length() << endl;cout << "max_size=" << s.max_size() << endl;cout << "capacity=" << s.capacity() << endl;}


string的字符串比较::

  1. C ++字符串支持常见的比较操作符(>,>=,<,<=,==,!=),甚至支持string与C-string的比较(如 str<”hello”)。
    在使用>,>=,<,<=这些操作符的时候是根据“当前字符特性”将字符按字典顺序进行逐一得 比较。字典排序靠前的字符小,
    比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小(前面减后面)
    同时,string (“aaaa”) <string(aaaaa)。

  2. 另一个功能强大的比较函数是成员函数compare()。他支持多参数处理,支持用索引值和长度定位子串来进行比较。
    他返回一个整数来表示比较结果,返回值意义如下:0:相等 1:大于 -1:小于 (A的ASCII码是65,a的ASCII码是97)

void test3()
{// (A的ASCII码是65,a的ASCII码是97)// 前面减去后面的ASCII码,>0返回1,<0返回-1,相同返回0string A("aBcd");string B("Abcd");string C("123456");string D("123dfg");// "aBcd" 和 "Abcd"比较------ a > Acout << "A.compare(B):" << A.compare(B)<< endl;                          // 结果:1// "cd" 和 "Abcd"比较------- c > Acout << "A.compare(2, 3, B):" <<A.compare(2, 3, B)<< endl;                // 结果:1// "cd" 和 "cd"比较 cout << "A.compare(2, 3, B, 2, 3):" << A.compare(2, 3, B, 2, 3) << endl;  // 结果:0// 由结果看出来:0表示下标,3表示长度// "123" 和 "123"比较 cout << "C.compare(0, 3, D, 0, 3)" <<C.compare(0, 3, D, 0, 3) << endl;    // 结果:0}


string的插入:
push_back() 和 insert()

void  test4()
{string s1;// 尾插一个字符s1.push_back('a');s1.push_back('b');s1.push_back('c');cout<<"s1:"<<s1<<endl; // s1:abc// insert(pos,char):在制定的位置pos前插入字符chars1.insert(s1.begin(),'1');cout<<"s1:"<<s1<<endl; // s1:1abc
}


string拼接字符串:
append() & + 操作符

void test5()
{// 方法一:append()string s1("abc");s1.append("def");cout<<"s1:"<<s1<<endl; // s1:abcdef// 方法二:+ 操作符string s2 = "abc";/*s2 += "def";*/string s3 = "def";s2 += s3.c_str();cout<<"s2:"<<s2<<endl; // s2:abcdef
}


string的遍历:借助迭代器 或者 下标法

void test6()
{string s1("abcdef"); // 调用一次构造函数// 方法一: 下标法for( int i = 0; i < s1.size() ; i++ ){cout<<s1[i];}cout<<endl;// 方法二:正向迭代器string::iterator iter = s1.begin();for( ; iter < s1.end() ; iter++){cout<<*iter;}cout<<endl;// 方法三:反向迭代器string::reverse_iterator riter = s1.rbegin();for( ; riter < s1.rend() ; riter++){cout<<*riter;}cout<<endl;
}

string的删除:erase()

  1. iterator erase(iterator p);//删除字符串中p所指的字符

  2. iterator erase(iterator first, iterator last);//删除字符串中迭代器

区间[first,last)上所有字符

  1. string& erase(size_t pos = 0, size_t len = npos);//删除字符串中从索引

位置pos开始的len个字符

  1. void clear();//删除字符串中所有字符
void test6()
{string s1 = "123456789";// s1.erase(s1.begin()+1);              // 结果:13456789// s1.erase(s1.begin()+1,s1.end()-2);   // 结果:189s1.erase(1,6);                       // 结果:189string::iterator iter = s1.begin();while( iter != s1.end() ){cout<<*iter;*iter++;}cout<<endl;
}

string的字符替换:

  1. string& replace(size_t pos, size_t n, const char *s);//将当前字符串从pos索引开始的n个字符,替换成字符串s

  2. string& replace(size_t pos, size_t n, size_t n1, char c); //将当前字符串从pos索引开始的n个字符,替换成n1个字符c

  3. string& replace(iterator i1, iterator i2, const char* s);//将当前字符串[i1,i2)区间中的字符串替换为字符串s

void test7()
{string s1("hello,world!");cout<<s1.size()<<endl;                     // 结果:12s1.replace(s1.size()-1,1,1,'.');           // 结果:hello,world.// 这里的6表示下标  5表示长度s1.replace(6,5,"girl");                    // 结果:hello,girl.// s1.begin(),s1.begin()+5 是左闭右开区间s1.replace(s1.begin(),s1.begin()+5,"boy"); // 结果:boy,girl.cout<<s1<<endl;
}

string的大小写转换:tolower()和toupper()函数 或者 STL中的transform算法

  • 方法一:使用C语言之前的方法,使用函数,进行转换
#include <iostream>
#include <string>
using namespace std;int main()
{string s = "ABCDEFG";for( int i = 0; i < s.size(); i++ ){s[i] = tolower(s[i]);}cout<<s<<endl;return 0;
}
  • 方法二:通过STL的transform算法配合的toupper和tolower来实现该功能
#include <iostream>
#include <algorithm>
#include <string>using namespace std;int main()
{string s = "ABCDEFG";string result;transform(s.begin(),s.end(),s.begin(),::tolower);cout<<s<<endl;return 0;
}

string的查找:find()

  1. size_t find (constchar* s, size_t pos = 0) const; //在当前字符串的pos索引位置开始,查找子串s,返回找到的位置索引,-1表示查找不到子串

  2. size_t find (charc, size_t pos = 0) const; //在当前字符串的pos索引位置开始,查找字符c,返回找到的位置索引, -1表示查找不到字符

  3. size_t rfind (constchar* s, size_t pos = npos) const;//在当前字符串的pos索引位置开始,反向查找子串s,返回找到的位置索引, -1表示查找不到子串

  4. size_t rfind (charc, size_t pos = npos) const; //在当前字符串的pos索引位置开始,反向查找字符c,返回找到的位置索引,-1表示查找不到字符

  5. size_tfind_first_of (const char* s, size_t pos = 0) const; //在当前字符串的pos索引位置开始,查找子串s的字符,返回找到的位置索引,-1表示查找不到字符

  6. size_tfind_first_not_of (const char* s, size_t pos = 0) const; //在当前字符串的pos索引位置开始,查找第一个不位于子串s的字符,返回找到的位置索引,-1表示查找不到字符

  7. size_t find_last_of(const char* s, size_t pos = npos) const; //在当前字符串的pos索引位置开始,查找最后一个位于子串s的字符,返回找到的位置索引,-1表示查找不到字符

  8. size_tfind_last_not_of (const char* s, size_t pos = npos) const; //在当前字符串的pos索引位置开始,查找最后一个不位于子串s的字符,返回找到的位置索引,-1表示查找不到子串

void test8()
{string s("dog bird chicken bird cat");//字符串查找-----找到后返回首字母在字符串中的下标// 1. 查找一个字符串cout << s.find("chicken") << endl;        // 结果是:9// 2. 从下标为6开始找字符'i',返回找到的第一个i的下标cout << s.find('i',6) << endl;            // 结果是:11// 3. 从字符串的末尾开始查找字符串,返回的还是首字母在字符串中的下标cout << s.rfind("chicken") << endl;       // 结果是:9// 4. 从字符串的末尾开始查找字符cout << s.rfind('i') << endl;             // 结果是:18-------因为是从末尾开始查找,所以返回第一次找到的字符// 5. 在该字符串中查找第一个属于字符串s的字符cout << s.find_first_of("13br98") << endl;  // 结果是:4---b// 6. 在该字符串中查找第一个不属于字符串s的字符------先匹配dog,然后bird匹配不到,所以打印4cout << s.find_first_not_of("hello dog 2006") << endl; // 结果是:4cout << s.find_first_not_of("dog bird 2006") << endl;  // 结果是:9// 7. 在该字符串最后中查找第一个属于字符串s的字符cout << s.find_last_of("13r98") << endl;               // 结果是:19// 8. 在该字符串最后中查找第一个不属于字符串s的字符------先匹配t--a---c,然后空格匹配不到,所以打印21cout << s.find_last_not_of("teac") << endl;            // 结果是:21}

string的排序:sort(s.begin(),s.end())

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;void test9()
{string s = "cdefba";sort(s.begin(),s.end());cout<<"s:"<<s<<endl;     // 结果:abcdef
}

string的分割/截取字符串:strtok() & substr()

void test10()
{char str[] = "I,am,a,student; hello world!";const char *split = ",; !";char *p2 = strtok(str,split);while( p2 != NULL ){cout<<p2<<endl;p2 = strtok(NULL,split);}
}

void test11()
{string s1("0123456789");string s2 = s1.substr(2,5); // 结果:23456-----参数5表示:截取的字符串的长度cout<<s2<<endl;
}

By --Suki

CAUC算法与数据结构复习基本代码(一)相关推荐

  1. 【软考】算法与数据结构复习指南

    1.算法 根据考试大纲,本章要求考生掌握以下几个方面的知识点. (1)数据结构设计:线性表.查找表.树.图的顺序存储结构和链表存储结构的设计和实现. (2)算法设计:迭代.穷举搜索.递推.递归.回溯. ...

  2. KPM算法——数据结构|复习局|串|复杂模式匹配算法|二维数组解决KPM

    数据结构复习局--KPM算法 何为KPM? 事先规则 状态 匹配 dp--状态转移图 状态X 获得dp数组值 看看图再理解下 写在前面: 本文仅为作者个人学习记录,详细具体内容参考自知乎大佬labul ...

  3. 名词解释 算法的有限性_数据结构复习之【数据结构和算法概念】

    一.概念 数据结构就像是一个催化剂,如果没有原料是无用的,单是有了算法就能帮算法更快的实现任务: 数据结构:是指相互之间存在一种或多种特定关系的数据元素的集合,简单地说是数据之间的各种关系的集合. 程 ...

  4. 【数据结构复习】二叉树的遍历——从微软2014校园招聘说起

    [数据结构复习]是学习.复习常用数据结构系列文章.数据结构与算法密不可分,是程序实现功能的重要组成部分.优秀的数据结构可以提高算法的时间及空间效率.反之,将增加算法复杂度,甚至妨碍程序的正确执行. 一 ...

  5. 算法与数据结构基础<一>----线性查找法

    开篇: 对于数据结构及算法的学习在17年时就已经在博客中开了专栏: 但是!!!感觉学得有点零散,有c版本的,也有java版本的,没成体系,当然其效果也并没达到自己满意的效果,基于此,这里准备重新开个专 ...

  6. 算法与数据结构+一点点ACM从入门到进阶吐血整理推荐书单

    前言:技术书阅读方法论 一.速读一遍(最好在1~2天内完成) 人的大脑记忆力有限,在一天内快速看完一本书会在大脑里留下深刻印象,对于之后复习以及总结都会有特别好的作用. 对于每一章的知识,先阅读标题, ...

  7. 数据结构复习-基础、线性表、栈、队列、串

    数据结构复习笔记 作者: 收集于网络 第一章:概论 数据:指所有能被输入到计算机中,且能够被计算机识别.存储和加工处理的信息的载体,是计算机操作的对象的总称. 数据元素:数据的基本单位,有时一个数据元 ...

  8. 史上最系统的算法与数据结构书籍推荐!!!!!吐血整理!!

    史上最系统的算法与数据结构书籍推荐!!!!!吐血整理!! 史上最系统的算法与数据结构书籍推荐!!!!!吐血整理!! 前言:技术书阅读方法论 一.速读一遍(最好在1~2天内完成) 人的大脑记忆力有限,在 ...

  9. 南京邮电大学计算机网络专硕,南京邮电大学计算机专硕数据结构复习经验分享...

    南京邮电大学计算机专硕数据结构复习经验分享 今年数学考砸了,考完了一直没想碰考研的任何东西.今天不知道怎么的突然觉得还是有必要给后人留下点 作者 magicls 次阅读 2014-01-28 今年数学 ...

最新文章

  1. luogu P4183 Cow at Large P (暴力吊打点分治)(内有时间复杂度证明)
  2. python段错误原因_python – 捕获崩溃的子进程的“分段错误”...
  3. TCP三次握手抓包观察实战篇
  4. Cocos2d-x中使用第三方so库
  5. 蔚来:4月交付7102台 同比增长125.1%
  6. qzone.class.php,[宜配屋]听图阁
  7. 再见2018,你好2019
  8. finalize()与PhantomReference学习笔记
  9. HTML兼容IE版本问题
  10. 【机械】如何用SOLIDWORKS进行ArtCam雕刻机排版
  11. 干货丨Kubernetes 中分析调试网络流量的4种方法
  12. mysql limit acs_Oracle Acs资深顾问罗敏 老罗技术核心感悟:牛! 11g的自动调优和
  13. 新中大软件ngpower6.1单机版安装流程(WIN11)
  14. 常见的积分商城游戏类型有哪些?
  15. 如何撰写出优秀的技术文档
  16. PPT科研绘图:将PPT绘制的图像保存为高清图片
  17. matlab近红外光谱曲线,Matlab关于偏最小二乘法应用于近红外光谱分析的问题
  18. 中国各大银行网址及服务电话
  19. 数据库打不开的解决办法
  20. 随着我国经济的持续快速发展,城市轻物流需求大幅增长

热门文章

  1. 上海地铁颜色配对色码值
  2. 什么是CNAS认证?为什么要选择具备CNAS资质的软件测试公司?
  3. PHP开源CRM-推荐几个
  4. Oracle 11g 64位 下载
  5. 分享给好友功能的实现
  6. PMP证书含金量高吗,在国内有什么用?
  7. python股票交易系统瘫痪_熬了一晚上,小白用Python写了一个股票提醒系统
  8. Patternodes 2 for Mac(图案花纹重复设计工具)
  9. mac室内设计软件_MyFourwalls(家居设计软件) V1.0.10 Mac版
  10. 汉字----dgfont