0

I want to generate all the strings of length from 1 to 10 by only words '4' and '7' in sorted order

  example-> 1)4 //first string

            2)7 //second string

            3)44 //third,because next after 7 should be 44

            4)47 //fourth,after 44

            . . .

            . . .

            . . .

            This way till length <=10

I tried myself and my backtracking code looks something like this

        #include<bits/stdc++.h>
        using namespace std;
        vector<string>v;                // for storing intermediate string in backtracking
        void generate(string s,char ch)
        {
            if(s.length()>=9)return;    //length > 10 returning
            s+=ch;                      //adding to string a new character
            v.push_back(s);                    //storing strings
            generate(s,'4');            //first backtracking
            generate(s,'7');            //second backtracking
        }
        int main()
        {
        generate("",'4');
        sort(v.begin(),v.end());     //sorting  to get ascending order string
        string thisfind;             //to find postion of string thisfind in vector...like postion of '4' is 1
        cin>>thisfind;
        int l=find(v.begin(),v.end(),thisfind)-v.begin();  //just usual find function
        cout<<l+1<<endl;            //output
        return 0;
    }

This is not correct please propose a backtracking algorithm to do the same

Note:- No worries of time-complexity

HANOI I
  • 13
  • 3
  • Thanks :) updated the question.See last line please – HANOI I Sep 09 '15 at 21:32
  • 1
    Already done this rant once today, but what complete and utter expletive deleted moron told you to do this: `#include` and `using namespace std;`? – user4581301 Sep 09 '15 at 21:33
  • I'll do the rant again. `#include` includes virtually the entire gnu port of the c standard library into your file. This has a number of problems, but the biggie is you've included massive amounts of stuff into your program that sets you up for a naming collision nightmare. `using namespace std;` places the std namespace into the global namespace. All those potential naming collisions just became very real. You have a function named `swap`? So does the standard library. And it's templated. It is legion. Find? Copy? Move? You're walking in a Minefield. – user4581301 Sep 09 '15 at 22:12

2 Answers2

2

Backtracking is not required, as a very simple algorithm exists that always does the right thing:

  • Start with the empty word. (As you require length > 0 this need not be printed)

  • After having done the work for size n - 1, you can do it for size n by:

    • Printing every word of size n - 1 prefixed with a "4"
    • Followed by printing every word of size n - 1 prefixed with a "7"

Since every move you do is guaranteed to move in the right direction (even in a recursive implementation that does not actually store anything explicitly), this would not really be backtracking - but why would you want to backtrack anyway?

P.S.: This algorithm is optimal: It spends O(1) time for each character it prints.

danielschemmel
  • 10,885
  • 1
  • 36
  • 58
  • Hi! I want backtracking solution for two reason.1) I am very poor with recursion so the more I deal with it the more perfect I become 2) Backtracking is the first thought that came to my mind so changing whole mindset and approach will not be feasible I guess :) – HANOI I Sep 09 '15 at 21:42
  • You did some kind of dfs/bfs i guess correct me if I am wrong – HANOI I Sep 09 '15 at 21:45
  • Try to pick the right tool for the job instead of insisting that the hammer you have in hand will work as a screwdriver as well. There is quite simply nothing to backtrack from in your problem (unless you make it by force, e.g. by randomly adding "5" so that you have a cause to backtrack). The approach I outlined can also be implemented recursively very nicely. – danielschemmel Sep 09 '15 at 21:46
  • Not really. I just realized that a list of words does not become unordered by adding a common prefix to each word. – danielschemmel Sep 09 '15 at 21:48
  • 1
    Argument 1 I can understand. Practice does make better, but consider: If someone on SO writes the algorithm for you, how much practice did you get? Argument 2 is inexcusable. If you can't change your mind when presented with a better solution, best to get out of science. – user4581301 Sep 09 '15 at 21:48
  • Thanks :) I will mark it correct answer.Is this question impossible to do this with backtracking.Tell me this so that I can move on. – HANOI I Sep 09 '15 at 21:55
  • It will be possible to do with backtracking, just not as easily or quickly. By all means, keep working on it because it is good practice and practice is good. When you get stuck on something concrete, ask SO. "Why does this work?" and "Why doesn't this work?" are usually good questions. – user4581301 Sep 09 '15 at 22:00
  • Backtracking basically means making a wrong choice that only becomes apparent later on, and then tracking back to the point where that choice was made. Of course you want to minimize the number of bad choices - so in a way this is a backtracking algorithm that just never needs to track back because it always makes the right choice. If you really want to backtrack, just make some bad choices (like "accidentally" adding a '5' instead of a '4'). – danielschemmel Sep 09 '15 at 22:18
  • Thanks,I learnt a new thing today.That's why I was asking a backtracking solution.You taught me new thing about backtracking :).Your answer is correct thanks again – HANOI I Sep 10 '15 at 05:04
1

I am writing answer to my own question.I found solution after investing some time on it.

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define ll long long int
vector<ll> v;
void recurse(ll num)
{
    v.push_back(num);
    if (num > ((ll)10e10))
        return;
    recurse(num * 10 + 4);
    recurse(num * 10 + 7);
}

int main()
{
    recurse(0);
    sort(v.begin(), v.end());
    ll n;
    cin >> n;
    cout << find(v.begin(),v.end(),n)-v.begin()<< endl;
    return 0;
}

Better algorithms already suggested but though I though sharing this would be good.

Shreevardhan
  • 12,233
  • 3
  • 36
  • 50
HANOI I
  • 13
  • 3