The secret of rotating strings

Keywords: WPF linq p2p

      Recently, Zhang children's shoes are very interested in string rotation, flipping and other issues. I watched some videos and did some topics. Now I have some new ideas and follow-up learning goals and plans to share with you  

catalog:

1: Introduce two methods to rotate the string as a whole
2: Rotate a single character and design a function (there are two methods, the first is to design a function, and the second is the three-step flip method: it is particularly ingenious, which will be described in detail here
3: Title 1: rotate a string, and then the words are in reverse order

4: Find the string, this problem will explain the idea and code in detail
OK, let's look at this question first

Title: complete the reverse order of a string
Example: abcd
Output: dcba
(even number)

Example: abcde
Output: edcba
(odd number)

Idea 1: you can use a loop to implement it. Pass b a string into the array. Since it is an array, you can access it in the form of access subscript, and then output it in reverse order
No more nonsense, just go to the code (don't worry, there are comments after each code)

​
/*
Method 1: reverse order output of for loop:

Idea: it is the same as inputting numbers in reverse order. You can print directly in reverse order

*/

//Has been tested on the compiler, no problem
#include <stdio.h>
#include <string.h>
int main()
{
    char s[1000]={0};//Create an array to store strings. If the size is small, pay attention to the topic specification and variable initialization. Good habits must be developed
    scanf("%s",s);//Enter a string, or use gets
    int n=strlen(s);//Find out how many letters there are, and you can calculate the subscript by the way
    int i=0;//Variable initialization, don't forget
    for(i=n-1;s[i]!='\0';i--)//Output in reverse order from the subscript of the last letter
    {        
        printf("%c",s[i]);
              
      }
        
    return 0;
  }

​

Conclusion: This is train of thought 1. It's not difficult to understand. Next, let's look at train of thought 1 (2)

/*

Method 2: it is also completed by loop, but this is to realize string exchange by array. It is somewhat similar to this topic, but the essence is the same

This is quite similar to the string aggregation before pengge, so I want to put them together


*/
//Has been tested on the compiler, no problem
#include<stdio.h>
#include<string.h>
int main()
{
    char arr[1000]={0};
    int left=0,right=0,i=0;
    scanf("%s",arr);//You can also use gets when entering a string
    int n=strlen(arr);//In this way, I write all these conditions in the for loop, and you can also write them outside
    for(left=0,right=n-1;(right-left)>0;left++,right--)
    {
/*
1:One thing to note here is, is right left > 1 OK? The answer is no, because if you exchange an even number, the fifth and sixth elements, 6-5 = 1, will retreat if the conditions are not met, so it's OK when the right subscript is greater than the left subscript

2:Then you can exchange strings
 As like as two peas, we first create a temporary variable to store the elements of the left subscript. This is exactly the same as the three numbers.
Since the character type is exchanged, you must use char type to create temporary variables

*/
       char t=0;
       t=arr[left];
       arr[left]=arr[right];
       arr[right]=t;
       
      }

//After the exchange, just print it out at last

    printf("%s",arr);
  
   return 0;
 }
 

Now let's review the topic of string aggregation as follows:
Write code to demonstrate moving from multiple characters from two segments to the middle.

The idea is as follows (many words, detailed, please read patiently):
For example, I changed the # number of arr2 to welcome bit

First, you have to create two arrays arr1 and arr2 to store these two strings

Then, if the string has been stored in the array, you can use the form of accessing the array subscript to define the left subscript as 0 and the right subscript as sz-1
, but it can't be sz, because it's a string. At this time, we need to understand the strlen function. str is a string, len is a string, and Len is lengh, which means length. Therefore, this is the origin of the strlen function

So what should left and right be equal to?
int left=0;
int right=strlen(arr2)-1;

First of all, make sure that every element of arr1 is transferred to arr2, right? So let the left subscript of arr1 be put into the left subscript of arr2. Similarly, the right coordinate is the same

Because we pass every time, let's take a look at his change, right? Just add a print after the exchange,

Then this is a time. I subtract left + + and right. Can he converge in the middle?

So do you have to add a while loop? Is this the same as binary search? Binary search has to be done many times

OK, here's the idea. The code is as follows

#include <stdio.h>
#include <stdio.h>
#include <string.h>
//Has been tested on the compiler
int main()
{
    char arr1[]="welcome bit";
    char arr2[]="###########";
    int left=0;
    int right=strlen(arr2)-1;
    while(left<=right)
    {
        arr2[left]=arr1[left];//It must be noted that it is not (), it is []
        arr2[right]=arr1[right];
        printf("%s\n",arr2);//In this way, each printed line is added, and the effect is gathered from the middle
      //  sleep(1000); / / it can't be implemented on the mobile phone. Stay because the mobile phone doesn't have windows.h
        left++;
        right--;
    }
    return 0;
   }

  Well, come back to your senses. Well, you must know the array exchange method. Now let's see how the function is implemented

Method 3 is implemented by a function, which we define as a character exchange function,

Character exchange function

The idea is: if you want to exchange a string, you have to pass the beginning and end address of the string to the exchange function, and then exchange it in the form of pointers, and the function we define has to receive it with two pointers

Well, when we have this idea, let's knock the code

(1) : the beginning and end address > can be represented by the array name, because the array name represents the address of the first element, and the address of the end element is the string len gt h - 1

(2) : when parameters are passed to a user-defined function, we can use the left subscript pointer and the right subscript pointer to receive them,

(3) You can use a while loop or a for loop to exchange,

What are the conditions? We can think that when our left subscript < = right subscript, does this stop the exchange?

OK, here's the idea. The code is as follows:

#include<stdio.h>
#include<string.h>
void my_string_reverse(char*left,char*right)
{
//Exchange, the * and [] here are the same
    while(left<right)
    {
        char t=*left;
        *left=*right;
        *right=t;
//The exchange step must be written correctly
        left++;
        right--;
     }
       
}    
int main()
{
    char arr[1000]={0};//Good habit initialization
    scanf("%s",arr);
    int n=strlen(arr);
    my_string_reverse(arr,arr+n-1);//Pass the address of the first and last elements
//After that, let's print it and see if he has completed the exchange
    printf("%s",arr); 
    return 0;
 }

ok, this is the method of overall exchange. Let's talk more about how to exchange two characters of a string of characters? This can be left exchange or right exchange;

The title is as follows: add photos

 

In fact, the idea of each topic can be like this. First, it is necessary to clarify the content of the topic, what to do with something, what purpose to complete in the end, and what tools can be used to build the idea in turn,

Swap two (k) characters in a string, also known as left - hand string

The string to be rotated will change, so we can store it in the array, because the array elements can be changed,
Never use char*p="ABCDEF" to change the constant string

Then we will customize the function, my_string_left(arr,k) and pass the array of arr, where k is the number of rotations,
Then use char*str to receive arr and int k to receive K

Now that the transmission part has been solved, let's start thinking about how to realize it,

Now there is A string ABCDEF. If it is rotated, we can think like this. Save one of the A letters with A temporary variable, and then move BCDEF forward as A whole. Move forward, that is, use A for loop a[i-1]=a[i] (if the subscript is 0, the format can be written as a[i]=a[i+1],

Finally, after the exchange is completed in the loop, just put the temporary variable back to the last bit.

Well, that's the general idea. Now let's turn to the code,

#include<stdio.h>
#include<string.h>
void my_string_left(char*str,int k)
{
    int i=0,j=0;//initialization
    int n=strlen(str);//st is the address of the first element. If you don't understand it here, you can check the parameter type received by strlen. Here we offer you: unsigned int strlen(const char *str); obviously, str is a character pointer, and you have to receive the address later
  
    for(i=0;i<k;i++)//Complete the exchange in the for loop. There are n elements in total. Now take out the first element for future storage, and n-1 is left to move forward. Then, if you want to find the length, you have to use strlen to find it
    {
        char t=*str;//First: store the first element in a temporary variable and put it in the for loop to get a new character in the next loop after the end of this loop. If it is placed outside the for loop, only the first character will be obtained each time
        for(j=0;j<n-1;j++)
        {
            *(str+j)=*(str+j+1);//Secondly, the * (str) here is dereference. Find the address of the first element to find the first first element, and you can't find the first element without * str. if you don't have the address of the first element, how can you find the end element?      
         }
     
    //Finally: if there is a vacant location, store the first element
        *(str+n-1)=t;             
     }
}  
 
int main()
{
    
   char arr[1000]={0};//Initialization, good habit
   scanf("%s",arr);//When inputting a string, you don't need to take the address, and you can also use gets
   int k=2;//Pass the character to be rotated
//Pass left
   my_string_left(arr,k);//Custom function
   printf("%s",arr);//Last print
   
   return 0;
 }

OK, now that the left-hand rotation will be, is the right-hand rotation the same? Here, let's think for a while. Don't look at the code, hehe

Dextral: as like as two peas, change it slightly.
Think for yourself and look at the code

Right hand string

#include <stdio.h>
#include<string.h>
void my_string_right(char*str,int k)
{
    int i=0,j=0;
    int n=strlen(str);//str is the address of the first element. If you don't understand it here, you can check the parameter type received by strlen. Here is for you:    
    for(i=0;i<k;i++)//The second step is to complete the exchange in the for loop. There are n elements in total. Now take out the first element for future storage, and the remaining n-1 should be moved backward. Then, if you want to find the length, you have to use strlen to find it
    {
        char t=*(str+n-1);//First, store the last element in a temporary variable and put it in the for loop to obtain a new character in the next loop after the end of this loop. If it is placed outside the for loop, only the first character is obtained each time
        for(j=n-2;j>=0;j--)
        {
            *(str+j+1)=*(str+j);//Move back    
         }
     
    //Step 3: if there is a vacant location, store the last element
        *(str)=t;
             
     }
}  

int main()
{
    char arr[1000]={0};
   scanf("%s",arr);//When inputting a string, you don't need to take the address, and you can also use gets
   int k=2;//Pass the character to be rotated
//Right handed two
   my_string_right(arr,k);//Custom function
   printf("%s",arr);

   
     return 0;
 }

Well, come back to the idea. The above two codes rotate two characters on the left or right of a string, but let's think about it like this. One character on the right = three characters on the left
eg1:
ABCD > > right hand one > > DABC
==Left hand three > > DABC

eg2:
ABCD > > right hand two > > cdab
==Left hand six > > cdab
It has been tested, no problem. Brothers, don't worry

Let me return to the original question
Next, let's introduce a method, the three-step flip method, which can also flip strings. It's wonderful and worth tasting

Three step turnover method
1 flip left
2 right flip
3 overall turnover
As shown in the figure:

 

#include <stdio.h>
#include<string.h>
void my_string_right(char*str,int k)
{
    int i=0,j=0;
    int n=strlen(str);//str is the address of the first element. If you don't understand it here, you can check the parameter type received by strlen. Here is for you:    
    for(i=0;i<k;i++)//The second step is to complete the exchange in the for loop. There are n elements in total. Now take out the first element for future storage, and the remaining n-1 should be moved backward. Then, if you want to find the length, you have to use strlen to find it
    {
        char t=*(str+n-1);//First, store the last element in a temporary variable and put it in the for loop to obtain a new character in the next loop after the end of this loop. If it is placed outside the for loop, only the first character is obtained each time
        for(j=n-2;j>=0;j--)
        {
            *(str+j+1)=*(str+j);//Move back    
         }
     
    //Step 3: if there is a vacant location, store the last element
        *(str)=t;
             
     }
}  

int main()
{
    char arr[1000]={0};
   scanf("%s",arr);//When inputting a string, you don't need to take the address, and you can also use gets
   int k=2;//Pass the character to be rotated
//Right handed two
   my_string_right(arr,k);//Custom function
   printf("%s",arr);

   
     return 0;
 }

Well, here, rotate the string, whether it's multiple or any character rotation, you must be able to do it, and then come to a topic to consolidate it

The topics are as follows:

 

Method 1: violent exhaustive method: list all the possibilities you can think of, and then compare them one by one

To judge whether s2 is obtained by s1 rotation, you can let s1 rotate one first, compare, and then rotate another, compare. Here, you can use the for loop

Each time the outer for loop is cycled, it means that an exchange has been completed. At this time, compare it with the strcmp function to see if it is equal. If it is equal, jump out

 

#include <stdio.h>
#include <string.h>
#include <assert.h>
char is_pd_string_rotate(char*str1,char*str2)//The first type can be char or int
//char*str1 to receive Arr1 and char * STR2 to receive arr2
{
    assert(str1);
    assert(str2);
    int i=0,j=0;
    int n=strlen(str1);
    for(i=0;i<n;i++)
    {
        char t=*str1;//Step 1: record the starting position
        for(j=0;j<n-1;j++)
        {
            *(str1+j)=*(str1+j+1);//Step 2 move forward: if the front one is smaller than the back one, move forward
          
        }
       *(str1+n-1)=t;//Step 3: put the first element at the end
//After each comparison, if it is the same, return 1     
      if(strcmp(str1,str2)==0)
      {
          return 1;
       }    
   }//If this layer of for loop stops, it means that each one has been rotated, and there is no match. It means that s2 is not rotated by s1, so let's return 0
   return 0;
   
}
int main()
{
    
    char arr1[]="AABCD";//Remember that the array must be initialized
    char arr2[]="BCDAA";
    int ret=is_pd_string_rotate(arr1,arr2);
    if(ret==1)
    {
        printf("yes");
     }
    else
    {
        printf("no");
     } 
    
    
    
    return 0;
 }

Well, here, our code will be implemented. Another note is that this is shown in the figure. You must be careful when writing function types
Don't make my little mistake

Method 2: append your own string to determine whether the string contains

Idea: can we change this string to include all situations? The answer is yes,

First of all: we can append with string.
Second: at the end, just judge whether arr2 is a substring of arr1.

#include <stdio.h>
#include <string.h>
#include <assert.h>
char is_pd_string_rotate(char*str1,char*str2)//char can, int can
{
    assert(str1);
    assert(str2);
    if(strlen(str1)!=strlen(str2))
    { 
//The length of the two is different. It must be ok if the rotation returns 0
        return 0;
     }
//First, the string is appended,
       int len=strlen(str1);
       strncat(str1,str1,len);

    
//After completion, use the strstr function to see if it is a substring. If it is a substring, it will return a null pointer (specifically, you can check the strstr function by yourself
    char*ret=strstr(str1,str2);
    if(ret==NULL)
   {
       return 0;//That is, we can't find the substring
    }
    else
    {
        return 1;//If found, return 1
     }
 //There is another exception at this time. If their string length does not want to wait, it must not be obtained by rotation
    //So ah, just add an if judgment in front  
   
}

int main()
{    
    char arr1[]="AABCD";//Remember that the array must be initialized
    char arr2[]="BCDAA";
    int ret=is_pd_string_rotate(arr1,arr2);
    if(ret==1)
    {
        printf("yes");
     }
    else
    {
        printf("no");
     } 
    
        
    return 0;
 }

Summary: there are many library functions in C language, so it will be faster in execution and writing. It is more convenient than the previous custom functions.

============================================================
Next, let's look at the next question (let's think for 10min before looking at the code)
The title is shown in the figure:

  Let's start with the overall idea:

Idea: 1. First write a function that can be in reverse order (as we have in previous articles) (pass the address of the first element and the address of the last element of this sentence)
After passing it on, just look at the reverse order of individual words,

Specific ideas:
First, reverse the whole string, design a flip function, and then reverse each word. If you want to reverse the word, you must have the subscript of each word,
If you want a subscript, you have to take the pointer (or left, right subscript). The method is to pass the subscript to the array for calculation. Then you need to find the subscript
Method. If you find the subscript, if you encounter '\ 0', it is the end of the last word, and then the space after each word
, if you cycle to a time when it is not equal to a space, continue to look down until you encounter a space of a word, then start else. If else, pass it
That is, the left subscript is 0 and the right subscript is minus one. This is the reverse order of the word. Then, after else is finished, go through the for loop right + +. This is
The next word, and so on, completes the reverse order.

The method is to use the for loop and array to reverse the order

But the essence is still the key point to find the reverse order of the word, how to find the next word, and the processing of spaces and \ 0

#include <stdio.h>
#include <string.h>
void my_string_fz_reverse(char a[],char left,char right)
{
//The condition 1 before for is 0 accepted by char left and n-1 accepted by char right
    for(;(right-left)>0;)//Condition 3 is to put it in the back. Of course, brothers can put it in the front
  {
     char t=a[left];
     a[left]=a[right];
     a[right]=t;
     
     left++;
     right--;  
    }    
}
int main()
{
    
    char s[10000]={0};//Initialize to 0, good habit
    gets(s);
    int n=strlen(s);
//Pass 3 elements and 1 array at one time, because the for loop is used to flip; 2left left subscript and 3:right right right subscript
    my_string_fz_reverse(s,0,n-1);
    int left,right;
    for(left=0,right=0;s[right]!='\0';right++)
    {
//if you don't understand the following, there is a detailed description in front. Brothers can turn it over and have a good look
        if(s[right]!=' ') 
           continue;
        else
        {
            
            my_string_fz_reverse(s,left,right-1);
            left=right+1;
          }
          
     }
     my_string_fz_reverse(s,left,right-1);
     printf("%s",s);
    return 0;
  }

Well, that's method one.
Let's look at method 2:

Method 2: pointer plus loop is similar to method 1, but in another form

#include<stdio.h>
#include<string.h>
void reverse(char*left,char*right)
{
    while(left<right)
    {
      char t=*left;
      *left=*right;
      *right=t;
      left++;
      right--;
    }
        
}    
int main()
{
    
   char arr[1000]={0};
   int left,right;
   get(arr);//Enter a string of words
   int n=strlen(arr);
   reverse(arr,arr+n-1);//This is the reverse order of the exchange whole
//   Then reverse the order of individual words, you have to use double pointers
   char*start=arr;
   while(*start)
   {
       char*end=start;
       while(*end!=' ' && *end!='\0')
       {
            end++;//This is the + + of the address, and then points to the next address; then it can be used for subsequent dereference to find the element
            
        }
       reverse(start,end-1);
       if(*end==' ')
         start=end+1;
       else
         start=end;       
     }
     
   printf("%s",arr);
    return 0;
 }

Well, this is today's content. The last question has nothing to do with today's content, but it can exercise our thinking:
The topics are as follows:

 

A three-tier for loop is used for step-by-step filtering
The premise is to pay attention to the inner nesting in for and the use of if

If you find a c in this string, see if the next one is h. if it is h, then see if it is n. if they are all satisfied, count + +, this one is chn. The same is true for other cases

As shown in the figure:

  Method 1: nesting of three-tier for loops and the usage of if statement and continue

/*
Method 1: use a three-layer for loop to filter step by step
 The premise is to pay attention to the inner nesting in for and the use of if


eg: To find the number of CHN S in CCHNCHN, first find C, and then judge. If the next letter is H, go down. If not,

For the first layer of the for loop, query the next word. When H is found, locate the next word to see if it is N. if it is N,

Then count + +. If there is still N after the first H, the z loop will continue to look back. The function of continue is

In this way, skip this cycle and proceed to the next cycle. If the conditions of the next cycle are met, judge and see whether the z cycle is met,




*/
#include <stdio.h>
int main()
{
   int count=0,i=0,j=0,z=0;
   char s[100]={0};
   scanf("%s",s);   
   for(i=0;s[i]!='\0';i++)
   {
       if(s[i]!='C')
         continue;
       if(s[i]=='C')
      {
          for(j=i+1;s[j]!='\0';j++)
          {
              if(s[j]!='H')
                 continue;
              if(s[j]=='H')
             {
                 for(z=j+1;s[z]!='\0';z++)
                 {
                     if(s[z]!='N')
                       continue;
                     if(s[z]=='N')
                       count++;
                   }
              }
          }
      }
   }
   
   printf("%d",count);
  return 0;
 }
/*Method 2: to find a string, you can point to the string with a pointer, and then point to it one by one with a for loop or an if loop
 For example, you still need to find several CHN S in CCHNCHN

C C H N C H N
0 1 2 3 4 5 6 

Entering the loop, * p points to the first element, not 0, so go back

Then there is the judgment part of if, the first C, indicating that it is found, c=1, jump out of the loop, p + + starts to point to the next element, or C, and then C becomes

2 After that, P + + looks back and finds that the third element is H. go else if this time ch=2. Then p + + starts looking for the second element and finds that it is N. then

At this time, CHN=2, then go down and find that it points to C. at this time, C becomes 3, then go on and encounter N. at this moment, CH=2+3=5, the most important

The latter character encounters N, and then goes to CHN. In this statement, the current CHN=2+5=7, so there are 7 CHNS.






*/
#include<stdio.h>
int main()
{
   int c=0;
   long int ch=0;
   long long int chn=0;
   char arr[100]={0};
   scanf("%s",arr);
   char*p=arr;//Use the pointer variable p to receive the array name of an arr
   while(*p)//*p will point because it will move back
   {
       if(*p=='C')
         c++;
       else if(*p=='H')
         ch+=c;
       else if(*p=='N')
         chn+=ch;
      
      p++;
    }
    printf("%d",chn);   
   return 0;
  }
  



*/
#include<stdio.h>
int main()
{
   int c=0;
   long int ch=0;
   long long int chn=0;
   char arr[100]={0};
   scanf("%s",arr);
   char*p=arr;//Use the pointer variable p to receive the array name of an arr
   while(*p)//*p will point because it will move back
   {
       if(*p=='C')
         c++;
       else if(*p=='H')
         ch+=c;
       else if(*p=='N')
         chn+=ch;
      
      p++;
    }
    printf("%d",chn);   
   return 0;
  }
  

Well, this is the topic of today's sharing. Then maybe there will be some miscellaneous and repetition in my narration. I hope you can bear to read it. I hope this blog will help you. The ideas inside can help you deal with some similar problems.

 

 

 

Posted by faraway on Tue, 30 Nov 2021 21:23:54 -0800