Novice entry programming needs to master several violent algorithms c/c + + and convenient data structures

Posted by Waldir on Mon, 31 Jan 2022 05:28:59 +0100

I will put some main knowledge points that need to be used next to the introduction of the algorithm, and I introduce an algorithm by solving a problem rather than directly;

First: find the most value in an array

Challenge arena method:

const int inf=10e9;

int main(){
    int n; scanf("%d",&n);

    int min=inf,max=-inf;//Set the maximum and minimum values small enough and large enough

    while(n--){

        int mid; scanf("%d",&mid);
   
        if(mid>=max) max=mid;
  
        if(mid<=min) min=mid;

    }

        printf("min=%d max=%d",min,max);

}

Sorting method: as the name suggests, it is sorting, so only two endpoints are needed;

Let's start with an easy but inefficient algorithm: bubble sorting: [array, loop]

#include<stdio.h>

const int N = 1000010;

int st[N],n;//st is used to store numbers, while n is used to record how many numbers there are

void swap(int &a, int &b) {
	int mid = a;
	a = b;
	b = mid;
}

int main() {
	scanf("%d", &n);

	for (int i = 0; i < n; i++) {

		scanf("%d", &st[i]);

	}

	int m=n;//Why record an m=n here? I hope you can think about it

	while (m--) {

		for (int i = 0; i < m; i++) {

			if (st[i] > st[i + 1]) 
				swap(st[i], st[i + 1]);//I directly create a function to realize the exchange to make the code look better. If you are not familiar with the function, you can exchange it with intermediate variables;
			

		}

	}

	for (int i = 0; i < n; i++)//Output array
		printf("%d ", st[i]);


}

This sort is easy to understand, but the efficiency is very low. The time complexity is o(n^2). Generally, it can't run if there are 10000 data. At that time, it needs fast sorting and merging. Moreover, c + + comes with a fast sorting sort. However, in order to uphold the principle of long live understanding, this vegetable bird first puts the fast sorting code, and then talks about the usage of the sort function; [function, recursion]

#include<iostream>
using namespace std;

const int N = 100010;

int st[N];
int n;

int quick_sort(int min, int max) {

	if (min >= max)
		return 0;

	int l = min - 1, r = max + 1;

	int x = st[l + r >> 1];//L + R > > 1 is equivalent to (l+r)/2

	while (l < r) {
		
		do l++;
		while (st[l] < x);

		do r--;
		while (st[r] > x);

		if (l < r) {
			swap(st[l], st[r]);
		}


	}

	quick_sort(min, r);
	quick_sort(r+1, max);

}


int main(){
	cin >> n;

	for (int i = 0; i < n; i++) {
		cin >> st[i];
	}

	quick_sort(0, n - 1);

	for (int i = 0; i < n; i++) {
		cout << st[i] << ' ';
	}

}

The time complexity of fast scheduling is o(n*log n), which means that the more data, the efficiency difference between fast scheduling and bubbling is nonlinear. However, the basis of understanding fast scheduling is recursion. Many people may not be very familiar with recursion, because I believe most of the people who click in are novice programmers like this vegetable bird;

Then this rookie will introduce the sort sorting function in c + +; [pointer, function]

#include<iostream>
#include<algorithm>
using namespace std;

const int N = 100010;

int st[N],n;

int main() {

	scanf_s("%d", &n);

	for (int i = 0; i < n; i++)
		scanf_s("%d", &st[i]);

	sort(st, st + n);

	for (int i = 0; i < n; i++)
		printf("%d ",  st[i]);

}

Is it convenient for sort function to include algorithm function library?? Fast efficiency, and very easy to write!

The two arguments in the sort function are pointers at both ends of the range to be sorted in the array, sort(st,st+n); The range of is the whole array;

It should be noted that the function of sort is more than that, because it is only mentioned slightly here, so if you need to have an in-depth understanding, you can check other and detailed articles. Maybe one day when you learn it, this rookie will also send an article about sort;

Is there a faster and better written sorting algorithm than the above two?

Yes, of course. That's the fastest bucket row in the universe. Don't look at the whole name as low, but its time complexity is only o(n), which is already the theoretical limit, and there are only a few lines;

Let's take a look at the code first;

#include<iostream>
#include<algorithm>
using namespace std;

const int N = 100010;

int st[N],sort1[N];

int main() {

	int n; cin >> n;

	int maxnum = -1;

	for (int i = 0; i < n; i++) {
		scanf_s("%d", &st[i]);
		maxnum = max(maxnum, st[i]);
	}

	for (int i = 0; i < n; i++) {
		sort1[st[i]]++;
	}

	for (int i = 0; i <= maxnum; i++) {
		while (sort1[i] != 0) {
			cout << i<<' ';
			sort1[i]--;
		}
	}
}

The core idea of bucket row is to map the data to be sorted into the subscript of another array, and then output it in turn according to the subscript of another array;

But the bucket row has a big defect, that is, if the data is too large, it will explode the memory;

This needs a good thought;

------------------------------

Palindrome judgment of strings and numbers

I believe everyone knows what palindrome means. Now let me introduce some palindrome judgment algorithms;

Determine the number of palindromes: [loop, if]

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

const int N = 100010;

int main() {
	int num; scanf_s("%d", &num);

	int mid = num,re=0;

	while (mid) {

		re = re * 10 + mid % 10;
		mid /= 10;

	}
	if (re == num)
		puts("Yes");
	else
		puts("No");
}

The core statement here is re = re * 10 + mid% 10;

I always believe in the saying, "the best way to learn is to think."

Those who don't understand can walk through it with a pen;

Determine palindrome string: [loop, if]

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;

const int N = 100010;

int main() {
	char st[N];

	scanf("%s",st);

	for (int i = 0; i <= strlen(st); i++) {

		if (st[i] != st[strlen(st) - i - 1]) {
			puts("No");
			return 0;
		}

	}
	
	puts("Yes");
}

Here we will introduce a c + + container, string, which can easily store strings and do some operations that are difficult to achieve in c language;

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

const int N = 100010;

int main() {
	
	string a,b;//Call string to get a string header file containing c + +;

    cin>>a;//string input

    a[i]//string supports random access

	//The string in string can be compared in size according to the dictionary order. If you don't know the dictionary order, you can go to Baidu to check it;

	if (a > b) {
		puts("Yes");
	}

	//string supports operator operations

	a += b; //If abc is stored in a and efg is stored in b, then after a+=b, a is abcdefg;

	//string supports sort function operation;

	sort(a.begin(), a.end());//Use dictionary order to complete the ascending sorting in a string;

	//String supports accessing string length;

	int len = a.size();//a.size() returns a value of type int, which is the length of a string

	//string supports one click emptying

	a.clear();//Empty string



}

It is enough to master the above operations at ordinary times;

Then let me introduce a sharp tool function in c + +;

As the name suggests, the reverse() function can flip the data in the array or various containers, which is very simple. Judge whether a palindrome string is the same after it is flipped. If it is the same, it is a string

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;

const int N = 100010;

int main() {
	
	char st[N];
	scanf("%s", st);

	reverse(st, st + strlen(st));

	puts(st);
	
}

Like sort, the two arguments in the reverse function are pointers to the two endpoints of the range to be flipped in the array;

string also supports the reverse function

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

const int N = 100010;

int main() {
	
	string a; 
	
	cin>>a; 

	reverse(a.begin(), a.end());

	cout<<a;
	
}

--------------------------

De duplication;

Some questions may give you some ordered or disordered numbers to ask you to remove some duplicate numbers;

This is actually a good solution. If it is an ordered array, it can be arranged in buckets;

#include<iostream>
#include<algorithm>
using namespace std;

const int N = 100010;

int st[N],sort1[N];

int main() {

	int n; cin >> n;

	int maxnum = -1;

	for (int i = 0; i < n; i++) {
		scanf_s("%d", &st[i]);
		maxnum = max(maxnum, st[i]);
	}

	for (int i = 0; i < n; i++) {
		sort1[st[i]]++;
	}

	for (int i = 0; i <= maxnum; i++) {
		if(sort1[i] != 0) {
			cout << i<<' ';
		}
	}
}

Just change the while in the third loop to if;

However, there will still be big defects that day, and the number cannot be too large;

Then there is an algorithm that is faster and faster without additional space, but can only be used for ordered arrays, the double pointer algorithm. This algorithm is a little difficult to understand, so I just copy the notes I made before, ha:)

#include<iostream>
#include<algorithm>
using namespace std;

const int N = 100010;

int st[N];

int main() {

	int n; cin >> n;

	for (int i = 0; i < n; i++) {
		scanf_s("%d", &st[i]);
	}

	int j, i;

	for ( i = 0, j = 0; i < n; i++) {
		if (st[i + 1] != st[i]) {
			st[j] = st[i];
			j++;
		}
	}
	
	for (int i = 0; i < j; i++) {
		printf("%d ", st[i]);
	}
}

The principle is as follows:

Enter n numbers, sort and de duplicate:
Here J and i can be visualized as two people walking stairs, and the stairs are an increasing array, in which i will try to make each part of J reach a new height. At this time, the smart i thought of a way, i let J climb the stairs with himself at the same time, and ordered the stupid J to say, "if the ladder in front of you suddenly rises, then you go forward", After that, he takes a step forward, and then he will look back to see if he is at a new height. If it is not a new height, i will take a step forward, and then repeat the process just now until i find that i have reached a step, and then i who knows magic will use his little magic to keep himself at the same height of the ladder, Make the height of the first step in front of the ladder where j is located the same as yourself, and then receive the command, J will take a step forward. After seeing that the height of J is the same as yourself, i will continue to move forward Cycle back and forth until i reach the end of the stairs, which makes i find J at the same height as myself;

--------------

Questions about prime numbers:

We usually write the prime filter like this

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

const int N = 100010;

long long st[N];

int main() {
	
	int n; cin>>n;
	int flag=1;
	for(int i=1;i<=n;i++){

		for(int j=2;j*j<=i;j++){

			if(i%j==0){
				flag=0; break;
			}

		}

		if(flag) printf("%d ",i);
		flag=1;

	}

}

The time complexity of this is o(n*n^1/2). The time complexity is not excellent, but no additional array is required;

Let me introduce an algorithm that requires additional arrays and has a time complexity of o(n), prime sieve;

#include<iostream>
#include<algorithm>
using namespace std;

const int N = 10000010;

int st[N];

int main() {

	int n; cin >> n;

	for (int i = 2; i <= n; i++) {

		if (st[i] == 1)//If this number cannot be prime, then we skip it;
			continue;
		else {

			for (int j = 2 * i; j <= n; j += i) {
				st[j] = 1;//Mark all numbers that cannot be prime numbers;
			}

		}
	}

	for (int i = 1; i <= n; i++) {

		if (st[i] == 0)//The rest are prime numbers;
			cout << i<<' ';

	}

}

This prime sieve is actually mathematically proved. Its principle is to deny the multiples of all x except X. in this way, traverse one side of X from 2~n, and the rest that is not denied is prime;

In fact, this is similar to the bucket row, which is also based on the operation of subscripts;

Well, that's almost all. Some primary algorithms and convenient data structures will be updated in the future. If you think it's OK, you can click a thumb;

: )

Topics: C C++ Algorithm