Algoritmo de contenedor específico de c ++ (ordenar, fusionar, invertir, eliminar, único)

Los siguientes son todos los algoritmos de contenedor específicos, que son algoritmos específicos para c ++, list y forward_list.

Parte 1: fusión del algoritmo de la función miembro (solo para forward_list y list)

1. La quinta página p369 de la cartilla de c ++ dice que lst.merge (lst2) debe tener tanto lst como lst2 en orden, pero yo escribo mi propio programa, y ​​está bien tener tanto lst como lst2 en orden, ¿por qué?

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <forward_list>
#include <stack>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>
#include <list>
#include <algorithm>
#include <numeric>
using namespace std;
bool compare(const int ,const int);
int main()
{
forward_list<int> f1{1,2223,3,4,5,6};
forward_list<int> l1{7,8,9};
//f1.sort();这里根本就没有运行
//l1.sort();这里也根本没有运行
//下面merge算法添加第二个参数用于比较,但是结果却不给从小到大排列?
f1.merge(l1,compare);
//这里我才开始排序
f1.sort();
for(auto i : f1)
	cout << i << endl;

return 0;
}
bool compare(const int a,const int b)
{
return a < b;
}

Los resultados del código anterior que se ejecuta en ubuntu20.04 son los siguientes:

r@r:~/coml_/c++/chapter10/10.6$ g++ 2.cc -o 123
r@r:~/coml_/c++/chapter10/10.6$ ./123
1
3
4
5
6
7
8
9
2223

Pregunta: ¿Este algoritmo no es válido para diferentes tipos de contenedores? En otras palabras, un forward_list y el otro una lista no se pueden fusionar. Mi propio compilador es así.

Si el maestro lo sabe, dímelo. ¿Solo es posible fusionar contenedores del mismo tipo? ? ?

¿Y por qué agregué comparar en mi programa, pero los resultados en ejecución no están ordenados? ¿Para muebles? Explícame si tienes un maestro Por favor. Pequeño principiante principiante.

Parte 2: eliminar el algoritmo

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <forward_list>
#include <stack>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>
#include <list>
#include <algorithm>
using namespace std;
bool is_odd(const int );
int main()
{
//have not function parameter
forward_list<int> fint{1,2,3,45,5,32};
fint.remove(32);
for(auto i : fint)
	cout << i << endl;

//have function parameter
forward_list<int> fint2{1,2,3,4,5,6,7};
fint2.remove_if([](const int i){return (i % 2 == 0);});
//fint2.remove_if(is_odd);
cout << endl;
for(auto i : fint2)
	cout << i << endl;
return 0;
}
bool is_odd(const int i)
{
return (i % 2);
}

Preste atención a algunos problemas:

1. Si usa el algoritmo remove, el parámetro debe ser un valor de tipo de elemento. Si usa el algoritmo remove_if, entonces el parámetro es una función o expresión lambda, en resumen, es un predicado unario

2. La versión anterior de la función que no es miembro de remove no eliminará este elemento, porque es fácil eliminar este elemento después de devolver la posición. Pero ahora la versión de la función miembro remove o remove_if eliminará directamente este elemento. Porque es difícil eliminar este elemento usted mismo. Qué humano.

Agregue algunas líneas más de código a continuación y revise la función de vinculación (utilizada para la vinculación de parámetros). Para usarla, primero debe agregar el archivo de encabezado funcional y el espacio de nombres usando el espacio de nombres std :: marcadores de posición, no hay muchas tonterías, simplemente vaya al código:

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <forward_list>
#include <stack>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>
#include <list>
#include <algorithm>
#include <functional>
using namespace std::placeholders;
using namespace std;
bool is_odd(const int );
bool divide(const int ,const int);
int main()
{
//have not function parameter
forward_list<int> fint{1,2,3,45,5,32};
fint.remove(32);
for(auto i : fint)
	cout << i << endl;

//have function parameter
forward_list<int> fint2{1,2,3,4,5,6,7};
fint2.remove_if([](const int i){return (i % 2 == 0);});
//fint2.remove_if(is_odd);
cout << endl;
for(auto i : fint2)
	cout << i << endl;
//下面再作死一下,再编写一个bind函数调用算法remove_if
//顺便复习一下bind函数,当你编写的函数要求很苛刻的时候,bind可能越有用
//删除能被5整除且大于给定整数的数
forward_list<int> fint3{10,11,12,13,14,15,16,5,0};
//define given integer number
int key;
cout << "Enter given number:"<< endl;
cin >> key;
fint3.remove_if(bind(divide,_1,key));
for(auto i : fint3)
	cout << i << endl;

return 0;
}
bool is_odd(const int i)
{
return (i % 2);
}
//定义这个函数纯粹是为了作死,调用bind
bool divide(const int i,const int key)
{
   return (i % 5== 0 && i > key);

}

La tercera parte: inversa, el siguiente código contiene muchos archivos de encabezado innecesarios.

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <forward_list>
#include <stack>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
forward_list<int> f1{1,2,3,4};
f1.reverse();
for(auto i : f1)
	cout << i << endl;
return 0;
}

Resumen: Afortunadamente, esta función es simple y no tuvo tantos problemas como antes.

La cuarta parte: ordenar, originalmente planeado no explicar. Eche un vistazo más de cerca, la versión de ordenar con parámetros no agrega si, y debe escribir un programa para ejecutarlo:

 



#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <forward_list>
#include <stack>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
//have no parameter
forward_list<int> f1{1,2,3,4};
f1.reverse();
for(auto i : f1)
	cout << i << " ";
cout << endl;

//have parameter 
forward_list<int> f2{1,2,3,4,5,6,7,8,9,10};
//按照除以5的余数大小进行排序
f2.sort([](const int i,const int j){return (i % 5 < j % 5);});
 for(auto i : f2)
	 cout << i << " ";
 cout << endl;

return 0;
}



La versión de sort con predicado binario no agrega si después de ella, realmente Nima Niu B.

Parte 5: Único, no lo presentaré brevemente.

Estas dos funciones son funciones sobrecargadas ¿Hay alguna diferencia entre los parámetros de Nima y los que no tienen parámetros?

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <forward_list>
#include <stack>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
forward_list<int> f{1,2,3,4,5,4,5,1,2};
//sort the number by the remainder divided by 5
f.sort([](const int i,const int j){return (i%5 < j%5);});
//if remainder devided by 5 is the same,then equal
f.unique([](int i,int j){return (i %5 == j %5);});
for(auto i : f)
	cout << i << endl;
    return 0;
}

Resumen: para parámetros de predicado binario únicos, la función no agrega if. Vacas

Parte 3: algoritmo de empalme de la lista, algoritmo de empalme después de la lista de avance

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <forward_list>
#include <stack>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
/*forward_list*/
//member function 1:flst.splice_after(p,flst2),insert flst2 after p
forward_list<int> f1{1,2,3,4,5,6};
forward_list<int> f2{11,22,33};
f1.splice_after(f1.begin(),f2);
for(auto i : f1)
	cout << i << endl;

//f2 has no elements
for(auto j : f2)
	cout << j << endl;

//member function 2:flst.splice_after(p,lst2,p2),move elements which pointed by  p2's next interator 
//把p2位置之后的元素插入到p之后
forward_list<int> f21{21,23,24,35};
forward_list<int> f22{33,34,54,54};
f21.splice_after(f21.begin(),f22,++f22.begin());
for(auto i : f21)
	cout << i << " ";
cout << endl;
//member function3:flst.splice_after(p,lst2,b,e):把lst2中(b,e)中的元素移动到flst中p之后,注意(b,e)是两边开区间。
//把lst2的第二个到第五个元素移动到lst中
forward_list<int> lst{1,2,3,4};
forward_list<int> lst2{11,22,33,44,55,66,77,88};
int i = 0;
forward_list<int>::iterator p1 = lst2.begin(),p2 =lst2.begin();
while(i !=5)
{
++ p2;
++ i;
}
//now p2 point to 6th element of lst2,p1 point to 1th element of lst2
//注意这里(p1,p2)是两边开区间,因为forward_list本身的特性,是把p1后面且p2前面的元素移动到lst中
lst.splice_after(lst.before_begin(),lst2,p1,p2);
cout << "lst is:" << endl;
for(auto i : lst)
	cout << i << " ";
	cout << endl;
/*list*/
list<int> l1{1,2,3,4,5};
list<int> l2{11,22,33};
list<int> l3{1024,1025,1026};
l1.splice(l1.begin(),l2);
for(auto i : l1)
	cout << i << " ";
cout << endl;
cout << "list"<< " " << endl;
//member function 2: insert element which pointed by l3.begin() into l1(before ++ l1.begin())
l1.splice(++l1.begin(),l3,l3.begin());
for(auto i : l1)
	cout << i << " ";
cout << endl;
//member function 3:lst.splice(p,lst2,b,e):把lst2中的[b,e)中的元素移动到lst中的p之前,注意[b,e)是前面闭区间,后面开区间.

//把lst_new中第3-6个元素移动到lst2_new中
list<int> lst_new{20,21,22,23,24,25};
list<int> lst2_new{30,31,32,33,34,35,36,37,38};
int ii = 0,jj = 0;
list<int>::iterator it1 = lst2_new.begin();
list<int>::iterator it2 = lst2_new.begin();
while(ii != 2)
{
it1 ++;
ii ++;
}
while(jj != 6)
{
it2 ++;
++ jj;
}
lst_new.splice(lst_new.begin(),lst2_new,it1,it2);
cout << "print:" << endl;
for(auto i : lst_new)
	cout << i << " ";
	cout << endl;
return 0;
}

Resumen: las similitudes y diferencias entre los algoritmos splice y splice_after:

1. El empalme se inserta antes del iterador dado, y splice_after se inserta después de la posición del iterador dada, por ejemplo

lst.splice (p, lst2) inserte lst2 antes de p, flst.splice_after (p, flst2)

lst.splice (p, lst2, p2) inserta el elemento apuntado por p2 en lst2 antes de p, flst.splice (p, flst2, p2), inserta un elemento después de p2 en la parte posterior de p

lst.splice (p, lst2, b, e) inserta el elemento de [b, e) en lst2 antes de p , flst.splice (p, flst2, b, e) inserta el elemento de (b, e) en flst2 Para la parte de atrás de p

2. Resumen

lst.splice () inserta el intervalo [b, e) o el elemento al que apunta un iterador p2, y lo inserta delante de p

lst.splice_after inserta un elemento en el intervalo (b, e), o un elemento después de un cierto iterador p2 , el rango insertado y la posición insertada no son iguales, las posiciones de inserción splice_after están todas ubicadas después de un cierto iterador, empalme El la posición de inserción está antes de un cierto iterador.

El elemento insertado por empalme es exactamente a lo que se refiere el p2 tradicional o el intervalo cerrado de 9 antes de la apertura. El elemento insertado por splice_after es un elemento detrás de un elemento o un elemento con un rango en ambos lados.

Similitudes: Los tipos de las dos listas enlazadas (contenedores) que deben insertarse e insertarse son los mismos. Ambos son list o forward_list

Por cierto, también me deshice de los ejercicios después de clase. Aquí está la respuesta que escribí:

10.6 respuestas auto-escritas a ejercicios

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <forward_list>
#include <stack>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>
#include <list>
#include <algorithm>
using namespace std;

void print(const list<string> &);

int main(int argc,char *argv[])
{
//be careful:out must be specified to fstream::out or ofstream::out or 
//fstream::app,etc..
//注意,这里fstream 流的 out必须指明文件模式是 out模式或者app模式才能自动创建文件。否则打开文件会失败。
fstream in,out(argv[2],ofstream::out);
in.open(argv[1]);
if(!out)
	cout << "open file failure" << endl;

list<string> lstr;
string str;
while(in >> str)
{
lstr.push_back(str);
}
lstr.sort();
lstr.sort([](const string &s1,const  string &s2){return (s1.size() < s2.size());});
lstr.unique();
print(lstr);
cout << argv[1] << endl;
cout << argv[2] << endl;

for(auto i : lstr)
   out << i << endl;

   return 0;
}

void print(const list<string> &s)
{
	for(auto i : s)
		cout << i << " ";


}

Nota: El flujo de archivo de salida de C ++ debe especificarse como objeto de flujo, si es un objeto de flujo, debe especificarse el modo de salida o el modo de aplicación para crear el archivo automáticamente.

En otras palabras, el compilador no es responsable de crear archivos cuando el objeto de flujo de archivos fstream no nombra ningún modo.

Otro ejemplo de algoritmo de empalme

//以下例子都运行过全部通过
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <forward_list>
#include <stack>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
 forward_list<int> l1 {1,2,3,4,5},l2{6,7,8};
 //insert all elements of l2 to l1
 //l1.splice_after(l1.begin(),l2);
 //insert some element of l2 to l1
 //l1.splice_after(l1.before_begin(),l2,++l2.begin());
 //insert elements from a scope   of l2 to l2,note that the scope is (),rather than [),becouse forward_list
 l1.splice_after(l1.before_begin(),l2,l2.begin(),l2.end());
 for(auto i : l1)
         cout << i << endl;
return 0;
}


 

Supongo que te gusta

Origin blog.csdn.net/digitalkee/article/details/112594071
Recomendado
Clasificación