Here's the entirety of my code. The problem I'm having trouble with is in the sortArray function. The first part of that function is used to sort the words gathered in a text file from A to Z, the second part is meant to find any duplicate words, ie 'a' appearing 3, and moves that duplicate to the end of the array where it won't be found again, and then increases .WordAmt for that index by 1, so when everything's out put, it'll show the letter 'a' for an index and have a WordAmt of 3. Here's where I'm at so far.

// libraries necessary to run the program
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

//WordStruct used when sorting the array and removing duplicates. Holds Words and amount of that word.
struct WordStruct
{
    string Word;
    int WordAmt;
};


void openFile(ifstream &filein, string &fileLocation);

void charCount(ifstream &filein, int &charnumber, int &lineamount);

void reopenFile(ifstream &filein, string &fileLocation);

void populateStruct(ifstream &filein, WordStruct Words[1000], int &itemamount);

void sortArray(WordStruct Words[1000], int &itemamount);

void swap(WordStruct Words[1000], WordStruct Words2[1000]);

void outputResults(string fileLocation, int charnumber, int lineamount, WordStruct Words[1000], int itemamount);

/****************************
Function: main

Description: Calls all the functions and initalizes the variables needed.

Parameters: 

Return Value: None
***************************/
void main()
{
    ifstream fin;
    string fileloc;
    int charnum = 0;
    int lineamt = 0;
    WordStruct Words[1000];
    int itemamt = 0;

    openFile(fin, fileloc);

    charCount(fin, charnum, lineamt);

    reopenFile(fin, fileloc);

    populateStruct(fin, Words, itemamt);

    sortArray(Words, itemamt);

    outputResults(fileloc, charnum, lineamt, Words, itemamt);

    return;
}


/****************************
Function: openFile

Description: Opens the file entered in by the user. If the file couldn't be opened, 
it returns an error and asks for input again.

Parameters: ifstream filein - Deals with file tasks such as opening the file.
            string fileLocation - holds the string of the file location entered by the user.

Return Value: None
***************************/
void openFile(ifstream &filein, string &fileLocation)
{
    cout << "Hello! This program will open a text file of your choosing, and then output the amount of characters and lines,"
        << "as well as order all the words in the file from A to Z, along with counting the amount of times a word has been used." << endl;
    do
    {
        cout << "Please enter the name of the file (Include .txt at the end of the file's name)." << endl;

        cin >> fileLocation;

        filein.open(fileLocation.c_str());
        if (filein.is_open() == true)
        {
            return;
        }
        else
        {
            cout << "Error: File not found." << endl;
        } 
    } while (filein.is_open() == false);
}

/****************************
Function: charCount

Description: Counts the amount of characters that are within the file.
Also counts the amount of new lines the file has.

Parameters: ifstream filein - Deals with file tasks of getting characters and lines from the file using .get()
            int charnum - Holds the amount of characters found within the file.
            int newlines - Holds the amount of new lines found within the file.

Return Value: None
***************************/
void charCount(ifstream &filein, int &charnum, int &newlines)
{
    do
    {
        if (filein.get() == '\n')
        {
            newlines++;
            charnum++;
        }
        else
        {
            charnum++;
        }
    } while (!filein.eof());

    newlines++;

    return;
}

/****************************
Function: reopenFile

Description: Closes the file, clears it, then re-opens it.

Parameters: ifstream filein - Deals with file tasks.
            string fileLocation - holds the string of the file location entered by the user.

Return Value: None
***************************/
void reopenFile(ifstream &filein, string &fileLocation)
{
    filein.close();
    filein.clear();
    filein.open(fileLocation.c_str());
    return;
}

/****************************
Function: populateStruct

Description: Enters the amount of words in the file into the struct. Also adds word amount of 1 to that word's counter
and increases the itemamount variable.

Parameters: ifstream filein - Used to get the words from the file.
            WordStruct Words - Stores all the words found within the file. Also stores the amount of that word found.
            int itemamount - holds the amount of items, aka words, that were stored.

Return Value: None
***************************/
void populateStruct(ifstream &filein, WordStruct Words[1000], int &itemamount)
{
    while (filein >> Words[itemamount].Word)
    {
        Words[itemamount].WordAmt = 1;
        itemamount++;
    }
    return;
}

/****************************
Function: sortArray

Description: Sorts the array of Words into alphabetical order, A-Z, or, left to right. Also finds
duplicate words in the struct, removes them, and adds 1 to the word amount of that word.

Parameters: WordStruct Words - holds the Words and the amount a word found.
            int itemamount - holds the amount of items, words, there are.

Return Value: None
***************************/
void sortArray(WordStruct Words[1000], int &itemamount)
{
    string temp;
    int numtemp;
    for (int spot = 0; spot < itemamount - 1; spot++)
    {
        int minIndex = spot;
        for (int index = spot + 1; index < itemamount; index++)
        {
            if (Words[index].Word < Words[minIndex].Word)
            {
                minIndex = index;
            }
        }
        if (minIndex != spot)
        {

            temp = Words[minIndex].Word;
            Words[minIndex].Word = Words[spot].Word;
            Words[spot].Word = temp;

            numtemp = Words[minIndex].WordAmt;
            Words[minIndex].WordAmt = Words[spot].WordAmt;
            Words[spot].WordAmt = numtemp;

        }
        if (spot > 0)
        {
            Words[spot - 1].WordAmt++;
            temp = Words[itemamount - 1].Word;
            Words[itemamount - 1].Word = Words[spot].Word;
            Words[spot].Word = temp;
            itemamount--;
            spot--;
        }
    }
    return;
}
/****************************
Function: swap

Description: Swaps the index of one part of Words with another part. Used to change word order.

Parameters: ???

Return Value: None
***************************/
/*void swap(WordStruct Words[1000], WordStruct Words2[1000])
{   
    string temp;
    temp = Words[].Word;
    Words[secondIndex].Word = Words[firstIndex].Word;
    Words[firstIndex].Word = temp;
}*/

/****************************
Function: outputResults

Description: Outputs all information collected by the program.

Parameters: string fileLocation - holds the name of the file opened.
            int charnumber - Holds the amount of characters founds within the file.
            int lineamount - Holds the amount of lines in the file.
            WordStruct Words - holds the words and their word amount.
            int itemamount - Holds the amount of items aka words found.

Return Value: None
***************************/
void outputResults(string fileLocation, int charnumber, int lineamount, WordStruct Words[1000], int itemamount)
{
    cout << "File: " << fileLocation << endl
        << "Characters: " << charnumber << endl
        << "Lines: " << lineamount << endl;
    cout << "Word          Word Amount" << endl;
    for (int counter = 0; counter < itemamount; counter++)
    {
        cout << Words[counter].Word << "          " << Words[counter].WordAmt << endl;
    }
    return;
}

Recommended Answers

All 4 Replies

The first part of that function is used to sort the words gathered in a text file from A to Z, the second part is meant to find any duplicate words

Pro tip: If the description of your function includes the word 'also', it should probably be refactored into multiple functions.

Your function does the work of two functions, and those two tasks are wildly different. Therefore there should be two functions: one to sort, and one to remove duplicates. Given a sorted collection, removing duplicates is trivial, so they can be run in sequence. If you do this then the task is greatly simplified from removing duplicates during the sort.

The removing duplicates part has to be within that function. Even should be within that outer for loop.

The removing duplicates part has to be within that function.

That's a stupid requirement.

Even should be within that outer for loop.

I'm not entirely sure what you mean by that, but I'll assume that it means you can't split the tasks into two operations, and that both the sort and removal of duplicates must be interleaved.

If that's the case then I'd recommend using a temporary array to hold the result, then copying that result into the source array. The simplest method conceptually would be to find the smallest item starting at index 0 for every iteration of the outer loop (which would be infinite). If a smallest item isn't found, then you break from the loop. If it is found, count the occurrances from index 0 and copy those values into the next open slot of the temporary array. To make sure that duplicates aren't processed multiple times, you can set the counter for each instance of the smallest value to something like -1.

So in pseudocode:

# Sort and remove duplicates
while true
    min = 0
    found = a[min].count >= 0

    # Find the first unprocessed smallest item
    for i = 1 to N
        if a[i].count < 0
            continue

        if a[min].count < 0 or a[i].value < a[min].value
            found = true
            min = i
    loop

    if not found
        break

    count = 0

    # Count occurrences
    for i = 0 to N
        if a[i].value = a[min].value
            a[i].count = -1 # Mark as processed
            count = count + 1
    loop

    # Add to the temporary array
    temp[size].value = a[min].value
    temp[size].count = count - 1
    size = size + 1
loop

# Copy the temporary array into the source
for i = 0 to size
    a[i] = temp[i]
loop

N = size # Reset N

Finally got it, I just needed to add "&& Words[spot].Word == Words[spot - 1].Word" into the condition for if (spot > 0).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.