views:

131

answers:

4

Hello! So my goal is to make a function that has a partially filled array of characters as a formal parameter and deletes all repeated letters from the array. So I just need to read a .txt file with it's contents as something like "11 A B C a b c a A g g t " and have the program spit back out "A B C a b c g t"

As of now my program spits back "1 A B C a b c "

I'd really appreciate any help on this.

Here is what I have...

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

bool deleterepeat( char arraytocheck[], char lettertocheck, int length)
{
    bool onlistflag = false;
    {
    for (int i = 0; i < length; i++)
    {
     if (arraytocheck[i] == lettertocheck)
     {
      onlistflag = true;
     }
    }
    }
    return onlistflag;
}



int main()

{    
    const int MAX = 15;
    char inFile[MAX];
    char clearedList[MAX];
    int clearedlength = 0;

     cout << "Choose a file: ";
     cin.getline(inFile, 15);
     ifstream in(inFile);

    if(!in) {
     cout << "Cannot open input file.\n";
     return 1;
    }


    while(in) {
     in.getline(inFile, MAX);


     for (int i = 0; i < MAX; i++)
     {
      in >> inFile[i];
     }
     for (int i = 0; i < MAX; i++)
     {
      if (deleterepeat(clearedList, inFile[i], i) == false)
      {
       clearedList[clearedlength] = inFile[i];
       clearedlength++;
      }
     }

     for (int i = 0; i < clearedlength; i++)
     {
      cout << clearedList[i] << " ";
     }



     if(in) cout << inFile << endl;
    }

    cout << endl;
    cin >> inFile;

    in.close();

    return 0;
}
A: 

It is a simple stuff , i can give u process to do so....

1.Read a char from input array .

2.check whether it exists in output array.

3.if not then insert it to output array , repeat the process for all chars of input array.

Ashish
This algorithm has a bad runtime complexity and will become very slow for larger strings.
Frerich Raabe
+2  A: 

Sort your array first using the sort algorithm, then remove all adjacent duplicates using the unique algorithm.

Here's an example function which takes a string (a line read from your file) and returns a string with all the unique characters:

string getUniqueCharacters( string s )
{
    sort( s.begin(), s.end() );
    string::iterator newEnd = unique( s.begin(), s.end() );
    return string( s.begin(), newEnd );
}

For the input string 11 A B C a b c a A g g t, the above function yields 1ABCabcgt (note that the space character is treated like any other character).

This function has O(n * log n) complexity, so it's still reasonably fast even for long strings. Also, this algorithm also works if you have more than 256 characters (think of unicode) in your strings. Just change string to wstring and you're done.

Frerich Raabe
+1  A: 
#include <iostream>
#include <fstream>
using namespace std;

int main() {       
    string ins, outs; // resizable

    cout << "Choose a file: ";
    cin >> ins;
    ifstream in(ins);

    if(!in) {
        cout << "Cannot open input file.\n";
        return 1;
    }

    while(in >> ins){
        for(string::const_iterator it = ins.begin(); it != ins.end(); ++it){
            if(outs.find(*it, 0) == string::npos){
                outs.append(1, *it);
            }
        }
    }
    in.close();

    cout << outs << endl;

    return 0;
}

is what I think you were trying to do. But if you know you're working with ascii (still often a reasonable assumption) you can dramatically improve performance (from quadratic to linear time, if str.find() is linear) by just keeping an array bool seen[256] and using if(seen[*it]) instead of a search. Or, more extensibly, bringing in the STL map container, which would let you find a list of unique strings of arbitrary length.

Wang
+1 for mentioning O(n^2) complexity, and for pointing out extensibility issues.
Frerich Raabe
+1  A: 
std::string f(istream & is) {
    bool known[256] = { false };
    char ch;
    std::string result;
    while (is >> ch) {
        if (! known[ch] /* || std::ispace(ch) */) {
            result += ch;
            known[ch] = true;
        }
    }
    return result;
}

Or (untested)

struct NotAgain {
    NotAgain() {
        std::fill_n(&known_[0], 256, false);
    }
    bool operator()(char ch) {
        const bool r = known_[ch];
        known_[ch] = true;
        return r;
    }
private:
    bool known_[256];
};

void f(std::string & buffer) {
    buffer.erase(
            std::remove_if(
                buffer.begin(),buffer.end(),
                NotAgain()),
            buffer.end());
}

Or it can be easily used directly on stream_iterator. The idea is alway the same, have an array of 256 elements that remembers the characters already seen. Or course, it works well with characters as there is a small and limited number of them. This solution won't scale much. With bigger number of unique elements, you'll have to consider associative maps (std::map (tree) / std::unordered_map (hash))

Luc Hermitte