So I have a program that reads in a certain number of keys. An example would be
5 1 10 21 9 6 21 11 13 16 20
The text file example would be
Java 2 linux 3 fear 0 pool 2 do 0 red 1 lock. 1 I 0 random 2
I want my program to start at Java and depending on first key, which in this case is 5, would move over 5 elements leading to "red". And so on and so on. However, I have managed to read in all the data and put them into arrays, I am just having trouble figuring out how to move the pointer in the array.
Code:
#include <iostream>
#include <fstream>
using namespace std;
struct pieces {
char word[5];
int jump;
} ;
// Main Function
int main ()
{
// declare variables
int wordCount[2];
int keyCount[2];
int numKeys, numKeys2;
int numWords;
int keyAmount = 1;
int wordAmount = 23;
int keyarr[11];
pieces cypher[wordAmount];
char filename[10];
ifstream inData;
int temp[10];
//prompt user for input file
cout << " Enter file name: ";
cin >> filename;
inData.open(filename);
if(inData.is_open());
{
// read in data
for ( numKeys = numWords = 0; numKeys < keyAmount; numKeys++){
// read in num of words and keys
inData >> wordCount[numKeys] >> keyCount[numKeys];
//read in words followed by jump key
for( numWords = 0; numWords < wordAmount; numWords++){
inData >> cypher[numWords].word >> cypher[numWords].jump;
}
// read in the actual keys
for( numKeys2 = 0; numKeys2 < wordCount[numKeys]; numKeys2++){
inData >> keyarr[numKeys2];
}
}
//print out data
for( int j = 0; j < numKeys; j++){
cout << wordCount[j] << "\n";
cout << keyCount[j] << "\n";
}
cout << "\n";
for ( int i = 0; i < wordAmount; ++i){
cout << cypher[i].word << " ";
cout << cypher[i].jump << " ";
}
cout << "\nKeys: " << "\n";
for(int k = 0; k < 11; k++){
cout << keyarr[k] << " ";
}
cout << "\n";
}
inData.close();
return 0;
}
Related
I have to ask the user to put in an array size and then to ask the user to fill it out. When the user puts in a duplicate, the program should say "invalid" and the user is asked to replace the number. I am supposed to use traversing array search.
Like this example here:
Enter list size: 4
Enter value for index 0: 1
Enter value for index 1: 1
Invalid. Enter a new number: 2
Enter value for index 2: 5
Enter value for index 3: 6
This is my code so far:
#include <iostream>
using namespace std;
int main() {
int size;
cout << "Enter list size: ";
cin >> size;
int array1[size];
for (int i = 0; i < size; i++) {
cout << "Enter value for index " << i << ": ";
cin >> array1[i];
for (int j = i + 1; j < size; j++) {
if (array1[i] == array1[j]) {
cout << "Invalid! Enter a new value for index " << i << ": ";
cin >> array1[i];
}
}
}
return 0;
}
It does what was specified but the exercise probably was to write std::ranges::find.
#include <iostream>
#include <vector>
#include <cstddef>
#include <algorithm>
int main() {
size_t size;
std::cout << "Enter list size: ";
std::cin >> size;
std::vector<int> arr;
arr.reserve(size);
while(arr.size() < size) {
int t;
std::cout << "Enter value for index " << arr.size() + 1 << ": ";
std::cin >> t;
if (std::ranges::find(arr, t) == arr.end()) {
arr.push_back(t);
} else {
std::cout << "Invalid! ";
}
}
}
Try this approach, Every time user enter value helper function will check duplicate from already filled array
#include<iostream>
// Helper Function that will check duplicate from array
bool IsDuplicate (int arr[] ,const int idxSoFar, int element){
for(int i =0 ; i < idxSoFar ; i += 1 )
if( arr[i] == element){
std::cout << "Invalid! Enter a new value for index "<< idxSoFar + 1 << " : ";
return arr[i] == element;
}
return false;
}
int main () {
int size;
std::cout << "Enter list size: ";
std::cin >> size;
int array1[size];
for (int i = 0; i < size; i++) {
std::cout << "Enter value for index " << i << ": ";
do
std::cin >> array1[i];
while(IsDuplicate(array1 , i , array1[i]));
}
return 0;
}
I am trying to check whether there is any duplicate integer in the user input array. The problem is that the validation of the duplicate does not work properly and I have no idea why it is not showing the desired output. Following is the code:
#include <iostream>
using namespace std;
int main()
{
int length;
int arrValue;
cout << "Enter the length : ";
cin >> length;
int *arr = new int[length];
cout << "Enter " << length << " integers for array : ";
for(int i = 0; i < length; i++)
{
cin >> arr[i];
}
cout << "Array : ";
for(int i = 0; i < length; i++)
{
arrValue = arr[i];
for(int k = i + 1; k < length; k++)
{
if(arr[i] == arr[k])
{
cout << "Duplicate found" << endl;
break;
}
else
{
cout << arrValue << " ";
}
}
}
delete[] arr;
}
Current result (assuming no duplicate in user input):
Enter the length: 5
Enter 5 integers for array : 5 4 3 2 1
Array : 5 5 5 5 4 4 4 3 3 2
Expected result (assuming no duplicate in user input):
Enter the length: 5
Enter 5 integers for array : 5 4 3 2 1
Array : 5 4 3 2 1
Current result (assuming duplicate in user input):
Enter the length: 5
Enter 5 integers for array : 5 4 4 2 1
Array : 5 5 5 5 Duplicate found 4 4 3
Expected result (assuming duplicate in user input):
Enter the length: 5
Enter 5 integers for array : 5 4 4 2 1
Array : Duplicate found
I believe my loops is the source to the problem. The current result output 10 times and I do not understand why there will be so many same numbers appearing.
Do note that I am trying to apply the validation using loop only and not from C++ standard library.
The issue in your code is that you are printing out each array element every time a particular element is not matching another element. It seems that you only want to print out whether any duplicate values are found. For this, you can use a bool flag to indicate whether any element is duplicated:
bool found_dup = false;
for(int i = 0; i < length; i++)
for(int k = i + 1; k < length; k++)
if(arr[i] == arr[k])
{
found_dup = true;
break;
}
// else: don't print anything yet
and then at the end print out the array:
if (found_dup)
std::cout << "Duplicate found";
else
for(int i = 0; i < length; i++)
std::cout << arr[i] << " ";
You may achieve the program in a more enhanced way (where you don't need to define the length manually - notice the explanation given as comments in code):
#include <iostream> // for input/output operation
#include <vector> // for dynamic array management
#include <sstream> // to split the user inputs and assign them to the vector
#include <algorithm> // to sort the vector
#include <string> // to work with getline()
// using this statement isn't recommended, but for sake of simplicity
// and avoiding the use of std:: everywhere temporarily (for small programs)
using namespace std;
int main(void) {
vector<int> numbers;
vector<int> duplicates;
string input;
int temp;
// getting the user input as string
cout << "Enter the numbers: ";
getline(cin, input);
stringstream ss(input);
// splitting the user input string into integers and assigning
// them into the vector
while (ss >> temp)
numbers.push_back(temp);
// sorting the vector in increasing order
sort(numbers.begin(), numbers.end());
// getting the unique numbers (which are not repeated)
cout << "Unique numbers: ";
for (size_t i = 0, len = numbers.size(); i < len; i++) {
if (temp == numbers[i])
// if found a duplicate, then push into the 'duplicates' vector
duplicates.push_back(temp);
else
cout << numbers[i] << ' ';
temp = numbers[i];
}
// getting the duplicates
cout << "Total duplicates: ";
for (size_t i = 0, len = duplicates.size(); i < len; i++)
cout << duplicates[i] << ' ';
cout << endl;
return 0;
}
It'll output something like:
Enter the numbers: 1 4 8 9 3 2 3 3 2 1 4 8
Unique numbers: 1 2 3 4 8 9
Total duplicates: 1 2 3 3 4 8
Please change the if condition to something like this.
cout << "Enter the length : ";
cin >> length;
int *arr = new int[length];
cout << "Enter " << length << " integers for array : ";
for(int i = 0; i < length; i++)
{
cin >> arr[i];
}
cout << "Array : ";
for(int i = 0; i < length; i++)
{
arrValue = arr[i];
for(int k = i + 1; k < length; k++)
{
if(arrValue == arr[k]) //change here.
{
cout << "Duplicate found" << endl;
break;
}
else
{
cout << arrValue << " ";
}
}
}
delete[] arr;
}
I would also suggest to use a map data structure. Map allows you to count the frequency of numbers, and thus detect duplicates in linear time.
map<int, int> m; // specify the key-value data-type.
for(int i = 0;i<length;i++)
{
m[arr[i]]++;
}
map<int, int>::iterator it; // an iterator to iterate over the datastructure.
for(it = m.begin();it!=m.end();it++)
{
if(it->second>1) //it->second refers to the value(here, count).
{
cout<<it->first<<" "; //it->first refers to the key.
}
}
Your loops are actually iterating n-1 times for first element, n-2 times for second element etc., where n is the length of your array. This is why for 5 element array you have printed 5 4 times.
But generally, if the purpose is to detect duplicates in the array, this strategy is not the best one. Please note that having exemplary array 4 3 4, with current approach you will correctly detect for the first 4 that the third element is also 4 but once you will move to the third element, it will be marked as ok since it is not checked with the first one element.
You may consider another strategy: create another array of the n size. Then iterate through your original array and for each element check if that element is already in the new array. If you detect the presence, you may raise duplicate event. Otherwise you can add this element to the array.
It doesn't work because you're trying to print the same value everytime you find a different one. I got here a solution with one more array that will store the array. It would work too with just one array.
#include <iostream>
using namespace std;
int main()
{
int length;
int arrValue;
cout << "Enter the length : ";
cin >> length;
int *arr = new int[length];
int *noDuplicateArr = new int[length];
cout << "Enter " << length << " integers for array : ";
for(int i = 0; i < length; i++)
cin >> arr[i];
cout << "Array : ";
bool duplicateFound = false;
int noDuplicateArrLen = 0;
for(int i = 0; i < length && !duplicateFound; i++)
{
arrValue = arr[i];
int k;
for(k = i + 1; k < length; k++)
{
if(arrValue == arr[k])
{
duplicateFound = true;
break;
}
}
if (k == length)
noDuplicateArr[noDuplicateArrLen++] = arrValue;
}
if (duplicateFound)
{
cout << "Duplicate found";
}
else
{
for (int i = 0; i < noDuplicateArrLen; i++)
{
cout << noDuplicateArr[i] << " ";
}
}
delete[] arr;
delete[] noDuplicateArr;
}
Here is the version with just one array:
#include <iostream>
using namespace std;
int main()
{
int length;
int arrValue;
cout << "Enter the length : ";
cin >> length;
int *arr = new int[length];
cout << "Enter " << length << " integers for array : ";
for(int i = 0; i < length; i++)
cin >> arr[i];
cout << "Array : ";
bool duplicateFound = false;
int noDuplicateArrLen = 0;
for(int i = 0; i < length && !duplicateFound; i++)
{
arrValue = arr[i];
int k;
for(k = i + 1; k < length; k++)
{
if(arrValue == arr[k])
{
duplicateFound = true;
break;
}
}
if (k == length)
arr[noDuplicateArrLen++] = arrValue;
}
if (duplicateFound)
{
cout << "Duplicate found";
}
else
{
for (int i = 0; i < noDuplicateArrLen; i++)
{
cout << arr[i] << " ";
}
}
delete[] arr;
}
A given file contains pairs of <two-digit number, amount>. Then take a toss-up two-digit number (called X), and compute the win/loss amount. The win/loss rule is if the input number matches X, then it’s a win and the winning total is (amount * 70); otherwise, it’s a loss of (-amount).
For example: [ticket.txt]
09 10
13 15
25 21
If the toss-up number is 09, the win/loss amount of the ticket is (10 * 70 - 15 - 21)
If the toss-up number is 42, the win/loss amount of the ticket is (-10 - 15 - 21).
This is my beginner project. I stuck at calculating the win amount and lost amount.
This is my problem
#include <iostream>
#include <fstream>
using namespace std;
int line1[100]; // array that can hold 100 numbers for 1st column
int line2[100]; // array that can hold 100 numbers for 2nd column
int main()
{
int winNum, winAmount, lostAmount;
int num = 0; // num start at 0
ifstream inFile;
inFile.open("Ticket.txt"); //open File
if (inFile.fail())
{
cout << "Fail to open the file" << endl;
return 1;
}
cout << "Numbers from File: " << endl;
while (!inFile.eof()) // read File to end of file
{
inFile >> line1[num]; // read first column, the first column is the number that user choosing
inFile >> line2[num]; // read second column, the second column is the amount of money that user paying
cout << "\n" << line1[num] << "\t" << line2[num];
++num;
}
inFile.close();
cout << endl;
cout << "Enter the toss-up number: "; // enter the win number
cin >> winNum;
if (line1[num] == winNum)
{
winAmount = line2[num] * 70; // number user choose = win number, winAmount = winAmount * 70 - lostAmount
cout << winAmount;
}
else
{
lostAmount =- line2[num]; //number user choose != win number, the amount will be -lost amounts
cout << lostAmount;
}
cout << endl << endl;
system("pause");
return 0;
}
You can see result at the end of the code
#include <iostream>
#include <fstream>
using namespace std;
int line1[100]; // array that can hold 100 numbers for 1st column
int line2[100]; // array that can hold 100 numbers for 2nd column
int main()
{
int winNum, winAmount = 0, lostAmount = 0, result = 0;
int num = 0; // num start at 0
ifstream inFile;
ifstream inFile2;
int rowNumber = 0;
string line;
inFile.open("Ticket.txt"); //open File
inFile2.open("Ticket.txt");
if (inFile.fail())
{
cout << "Fail to open the file" << endl;
return 1;
}
while (getline(inFile2, line))
++rowNumber;
cout << "Number of lines in text file: " << rowNumber << "\n";
int myArray[rowNumber][2];
for(int i = 0; i < rowNumber; i++)
for(int j = 0; j < 2; j++)
inFile >> myArray[i][j];
cout << "Numbers from File: " << endl;
for(int i = 0; i < rowNumber; i++)
{
for(int j = 0; j < 2; j++)
{
cout << myArray[i][j] << " ";
}
cout << "\n";
}
cout << endl;
cout << "Enter the toss-up number: "; // enter the win number
cin >> winNum;
for(int i = 0; i< rowNumber; i++)
{
if (myArray[i][0] == winNum)
{
winAmount = myArray[i][1] * 70; // number user choose = win number, winAmount = winAmount * 70 - lostAmount
}
else
{
lostAmount = lostAmount + myArray[i][1]; //number user choose != win number, the amount will be -lost amounts
}
}
result = winAmount - lostAmount;
cout << result;
cout << endl << endl;
system("pause");
return 0;
}
When you test line1[num] == winNum (and all the operations carried out after that) you're using the value of num that you modified with ++num;, this means you're working with empty or not meaningful values for both line1 and line2. For example, if the 3 rows of values showed in your "ticket.txt" are used, they are stored in postions 0, 1 and 2 of the arrays, while the num has a value of 4 at the end.
If I understood what you are trying to achieve, you should put the if-else statement in a for loop that goes from 0 to num, and then every operation on line1 and line2 should be done with the looping variable as an index.
Also, move the cout just after the loop if you want only total amounts to be displayed.
This question already has answers here:
How to make cin take only numbers
(2 answers)
Closed 6 years ago.
So the requirements for this program is to be able to increment arrays of the same size (size from 5 to 15 indexes) and increment each element in the array by one using for and while loops. The last task is to take values from the first array and put them in reverse order and assign them to the second array.
So everything works as normal, and the program rejects invalid inputs and does not go into an infinite loop. However, the program accepts some inputs that are not wanted.
For example, I would input something like '12 a' or '7 asdfkla;j lasnfg jasklgn asfg' and it would go through. It is interesting too because the code registers only 12 or 7 and completely ignores the rest. I think it is because once it hits a non-integer character, it would stop ignore the rest.
Why is it ignoring the rest of the input? And is there a way to catch this error from going through?
Also, if you see anything that catches your eye, feel free to critique c: I am always looking to improving.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
srand(time(NULL));
int x;
int j = 0;
bool not_valid = true;
system("color f");
cout << "Program will ask for an input for the size of an array.\n"
<< "With the array size defined, program will generate semi-\n"
<< "true random integers from 0 to 8. First array will then\n"
<< "be assigned to the second in reverse (descending) order.\n\n";
do {
cout << "Enter array size (0 - 15): ";
cin >> x;
if (x >= 5 && x <= 15) {
not_valid = false;
cout << "\nArray size: " << x << endl;
}
else {
cout << "Invalid input.\n\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
} while (not_valid);
int *arr0;
int *arr1;
arr0 = new int[x];
arr1 = new int[x];
for (int i = 0; i < x; i++) {
arr0[i] = rand() % 9;
}
for (int i = 0; i < x; i++) {
arr1[i] = rand() % 9;
}
cout << "\nARRAY 0 (unmodified, for):\n";
for (int i = 0; i < x; i++) {
cout << arr0[i] << "\t";
}
cout << "\n\nARRAY 0 (modified, for):\n";
for (int i = 0; i < x; i++) {
arr0[i]++;
cout << arr0[i] << "\t";
}
cout << "\n\nARRAY 1 (unmodified, while):\n";
for (int i = 0; i < x; i++) {
cout << arr1[i] << "\t";
}
cout << "\n\nARRAY 1 (modified, while):\n";
while (j < x) {
arr1[j]++;
cout << arr1[j] << "\t";
j++;
}
int second = x - 1;
for (int i = 0; i < x; i++) {
arr1[second] = arr0[i];
second--;
}
j = 0;
cout << "\n\nARRAY 1 (array 0, descending):\n";
while (j < x) {
cout << arr1[j] << "\t";
j++;
}
cout << endl << endl;
system("pause");
return 0;
}
Take input in string and then check if it's a number or not.
Example:
#include<iostream>
#include<sstream>
#include <string>
using namespace std;
int main()
{
string line;
int n;
bool flag=true;
do
{
cout << "Input: ";
getline(cin, line);
stringstream ss(line);
if (ss >> n)
{
if (ss.eof())
{
flag = false;
}
else
{
cout << "Invalid Input." << endl;
}
}
}while (flag);
cout << "Yo did it !";
}
I am trying to write a program to count each number the program has encountered. by putting M as an input for the number of the array elements and Max is for the maximum amount of number like you shouldn't exceed this number when writing an input in the M[i]. for some reason the program works just fine when I enter a small input like
Data input:
10 3
1 2 3 2 3 1 1 1 1 3
Answer:
5 2 3
But when I put a big input like 364 for array elements and 15 for example for max. the output doesn't work as expected and I can't find a reason for that!
#include "stdafx.h"
#include <iostream>
#include<fstream>
#include<string>
#include <stdio.h>
#include<conio.h>
using namespace std;
int ArrayValue;
int Max;
int M[1000];
int checker[1000];
int element_cntr = 0;
int cntr = 0;
int n = 0;
void main()
{
cout << "Enter the lenght of the Elements, followed by the maximum number: " << endl;
cin >> ArrayValue>> Max;
for (int i = 0; i < ArrayValue; i++)
{
cin >> M[i];
checker[i]= M[i] ;
element_cntr++;
if (M[i] > Max)
{
cout << "the element number " << element_cntr << " is bigger than " << Max << endl;
}
}
for (int i = 0; i < Max; i++)
{
cntr = 0;
for (int j = 0; j < ArrayValue; j++)
{
if (M[n] == checker[j])
{
cntr+=1;
}
}
if (cntr != 0)
{
cout << cntr << " ";
}
n++;
}
}
You have general algorithm problem and several code issues which make code hardly maintainable, non-readable and confusing. That's why you don't understand why it is not working.
Let's review it step by step.
The actual reason of incorrect output is that you only iterate through the first Max items of array when you need to iterate through the first Max integers. For example, let we have the input:
7 3
1 1 1 1 1 2 3
While the correct answer is: 5 1 1, your program will output 5 5 5, because in output loop it will iterate through the first three items and make output for them:
for (int i = 0; i < Max; i++)
for (int j = 0; j < ArrayValue; j++)
if (M[n] == checker[j]) // M[0] is 1, M[1] is 1 and M[2] is 1
It will output answers for first three items of initial array. In your example, it worked fine because the first three items were 1 2 3.
In order to make it work, you need to change your condition to
if (n == checker[j]) // oh, why do you need variable "n"? you have an "i" loop!
{
cntr += 1;
}
It will work, but both your code and algorithm are absolutely incorrect...
Not that proper solution
You have an unnecessary variable element_cntr - loop variable i will provide the same values. You are duplicating it's value.
Also, in your output loop you create a variable n while you have a loop variable i which does the same. You can safely remove variable n and replace if (M[n] == checker[j]) to if (M[i] == checker[j]).
Moreover, your checker array is a full copy if variable M. Why do you like to duplicate all the values? :)
Your code should look, at least, like this:
using namespace std;
int ArrayValue;
int Max;
int M[1000];
int cntr = 0;
int main()
{
cout << "Enter the lenght of the Elements, followed by the maximum number: " << endl;
cin >> ArrayValue >> Max;
for (int i = 0; i < ArrayValue; i++)
{
cin >> M[i];
if (M[i] > Max)
{
cout << "the element number " << i << " is bigger than " << Max << endl;
}
}
for (int i = 0; i < Max; i++)
{
cntr = 0;
for (int j = 0; j < ArrayValue; j++)
{
if (i == M[j])
{
cntr ++;
}
}
if (cntr != 0)
{
cout << cntr << " ";
}
}
return 0;
}
Proper solution
Why do you need a nested loop at all? You take O(n*m) operations to count the occurences of items. It can be easily counted with O(n) operations.
Just count them while reading:
using namespace std;
int arraySize;
int maxValue;
int counts[1000];
int main()
{
cout << "Enter the lenght of the Elements, followed by the maximum number: " << endl;
cin >> arraySize >> maxValue;
int lastReadValue;
for (int i = 0; i < arraySize; i++)
{
cin >> lastReadValue;
if (lastReadValue > maxValue)
cout << "Number " << i << " is bigger than maxValue! Skipping it..." << endl;
else
counts[lastReadValue]++; // read and increase the occurence count
}
for (int i = 0; i <= maxValue; i++)
{
if (counts[i] > 0)
cout << i << " occurences: " << counts[i] << endl; // output existent numbers
}
return 0;
}