-3

This is algorithm that counts the number of character shifts. How can I simplify this?

#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
#define SIZE 20
int w[1 << (SIZE + 1)];
bpaul
  • 3
  • 2
  • 12
    If you have a working program and just want tips on improving it, better place would be https://codereview.stackexchange.com/ – Yksisarvinen Jun 28 '19 at 12:06
  • 9
    simplify for readability? Use meaningful variable names – 463035818_is_not_an_ai Jun 28 '19 at 12:11
  • 2
    Add some documentation to your code that explains the idea how the algorithm works. – MrSmith42 Jun 28 '19 at 12:39
  • Welcome to StackOverflow. Please follow the posting guidelines in the help documentation, as suggested when you created this account. [On topic](https://stackoverflow.com/help/on-topic), [how to ask](https://stackoverflow.com/help/how-to-ask), and ... [the perfect question](https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/) apply here. StackOverflow is not a design, coding, research, or tutorial resource. Please check [Which site?](https://meta.stackexchange.com/questions/129598/which-computer-science-programming-stack-exchange-do-i-post-in) for general issues. – Prune Jun 28 '19 at 18:14

1 Answers1

1

You can simplify the function by using algorithms provided by C++.

In the below example code, we read 2 strings, then rotate one, and look, if it is equal to the other. We will repeat the operation, until we found a match, or, until we detect that there is no transformation possible. The code is commented and should be understandable. If not, then please ask.

#include <iostream>
#include <string>
#include <algorithm>

int main()
{
    std::string string1{};  std::string string2{};
    std::cout << "Enter 2 strings with same number of digits:\n";
    std::cin >> string1 >> string2; // Read strings
    // Strings must have same size
    if (string1.size() == string2.size()) {
        // Countes the number of rotations to the right
        size_t rotateCounter{0};
        do  {
            // If rotated string is equal to original, then we found something
            if (string1 == string2) break;
            // Rotate right
            std::rotate(string1.rbegin(),string1.rbegin()+1,string1.rend());
            // We have done one more rotation
            ++rotateCounter;
        } while(rotateCounter < string1.size());
        // CHeck, if we could find a solution
        if ((rotateCounter == string1.size()) && (string1 != string2))  {
            std::cout << "Total different strings. No rotation transformation possible\n";
        } else {
            std::cout << "Number of right shifts needed: " << rotateCounter << '\n';
        }
    } else {
        std::cerr << "Size of strings not equal\n";
    }
    return 0;
}

EDIT:

I created a 2nd version with arrays. I cannot imagine any reason why somebody wants to use arrays. Maybe for educational purposes. But also here I would find it counter-productive. Anyway. Please see below.

And please note std::rotate works also with plain arrays, as all algorithms do.

This has not been compiled and tested by me!

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
#include <cstring>

int main()
{
    std::cout << "Enter number of letters for a string: ";
    size_t numberOfLetters{}; std::cin >> numberOfLetters;
    if (numberOfLetters < 1000000)
    {
        // Create Array of char
        char* charArray1 = new char[numberOfLetters];
        char* charArray2 = new char[numberOfLetters];
        // Read the strings
        std::cout << "Enter s strings with excactly " << numberOfLetters << " digits:\n";
        std::string s1{}, s2{}; std::cin >> s1 >> s2;
        // Padding with spaces 
        s1.insert(0, numberOfLetters, ' ');s2.insert(0, numberOfLetters, ' ');

        // Copy the char Array
        s1.copy(charArray1, numberOfLetters);
        s2.copy(charArray2, numberOfLetters);

        // Countes the number of rotations to the right
        size_t rotateCounter{0};
        do  {
            // If rotated string is equal to original, then we found something
            if (0 == std::memcmp(charArray1, charArray2, numberOfLetters)) break;
            // Rotate right
            std::rotate(charArray1,charArray1+numberOfLetters-1,charArray1+numberOfLetters);
            // We have done one more rotation
            ++rotateCounter;
        } while(rotateCounter < numberOfLetters);
        // CHeck, if we could find a solution
        if (std::memcmp(charArray1, charArray2, numberOfLetters))  {
            std::cout << "Total different strings. No rotation transformation possible\n";
        } else {
            std::cout << "Number of right shifts needed: " << rotateCounter << '\n';
        }

        delete [] charArray1;
        delete [] charArray2;
    } else {
        std::cerr << "To many letters\n";
    }
    return 0;
}

And last but not least. The version with plain static arrays and a hand crafted rotate algorithm.

This should be sufficient. Maybe next time, very clear requirements would be helpful. Then we can select the correct solution.

#include <iostream>
#include <algorithm>
#include <iterator>

constexpr size_t MaxDigits = 1000000;

char LetterArray1[MaxDigits] {};
char LetterArray2[MaxDigits] {};

// Rotate array one char to the right
inline void rotateRight(char(&arrayToRotate)[MaxDigits], size_t numberOfLetters)
{
    --numberOfLetters;  
    char temp = arrayToRotate[numberOfLetters];
    for (size_t i = numberOfLetters; i > 0; --i) arrayToRotate[i] = arrayToRotate[i - 1];
    arrayToRotate[0] = temp;
}

int main() {
    // Get the number of letters that the user wants to use
    std::cout << "Enter the number of letters:   ";
    size_t numberOfLetters{ 0 }; std::cin >> numberOfLetters;
    // Check input for underflow or overflow
    if (numberOfLetters <= MaxDigits)
    {
        // Now read to strings from the console
        std::cout << "\nEnter  2 strings:\n";
        std::string inputString1{}; std::string inputString2{};
        // Read 2 strings
        std::cin >> inputString1 >> inputString2;
        // If user enters too short string, we would run into trouble. Therefore, pad string with spaces
        inputString1 += std::string(numberOfLetters, ' ');
        inputString2 += std::string(numberOfLetters, ' ');

        // Copy strings to array
        inputString1.copy(LetterArray1, numberOfLetters);
        inputString2.copy(LetterArray2, numberOfLetters);

        // So, now we have the 2 strings in our arrays
        // We will rotate Array1 and compare the result with Array 2. And we count the number of shifts
        bool matchFound{ false };
        size_t rotateCounter{ 0 };
        while (!matchFound && (rotateCounter < numberOfLetters))
        {
            if (0 == std::memcmp(LetterArray1, LetterArray2, numberOfLetters)) {
                matchFound = true; break;
            }
            rotateRight(LetterArray1, numberOfLetters);
            ++rotateCounter;
        }
        if (matchFound)     {
            std::cout << "\nNecessary rotations: " << rotateCounter << '\n';
        }
        else {
            std::cout << "\nNo Match Found\n";
        }
    }
    else {
        std::cerr << "***** Number of letters entered is to big. Max allowed: " << MaxDigits << '\n';
    }
    return 0;
}


A M
  • 14,694
  • 5
  • 19
  • 44
  • Ok, but i should used array and variable n(meanging number of letters). `n < 1000 000` – bpaul Jun 28 '19 at 13:44
  • FWIW, that a max is given in the reqs suggest the OP's teacher is expecting _not_ to use dynamic allocation (but instead a static storage array like the one shown in the question). Not that I'd do that. But hey. – Lightness Races in Orbit Jun 28 '19 at 15:07
  • Ohh, I insert `n = 4, inputString1 = AACB and inputString2 = BACA`. Results it's "Not Founds', but should be `output: 4`. – bpaul Jun 29 '19 at 12:39
  • Hm? I do not understand. How can we convert AACB to BACA with rotating? What would be the logic? Please ss: AACB --> BAAC --> CBAA --> ACBA --> AACB – A M Jun 29 '19 at 13:10