I'm trying to make a program that requires nested loops to work properly.
But the number of nested loops depend on the number of character the user inputs also the character to output.
This is my code so far.
#include<iostream>
using namespace std;
int main(){
string str;
cout<<"Enter some string: ";
cin>>str;
// for two characters
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2 ; j++){
cout<<str[i]<<str[j]<<endl;
}
};
// for four characters
for(int i = 0; i<4; i++){
for(int j=0;j<4;j++){
for(int k =0;k<4;k++){
for(int z=0;z<4;z++)
cout<<str[i]<<str[j]<<str[k]<<str[z]<<endl;
}
}
}
return 0;
}
So, is there any way to solve this issue.
You need to do it dynamically:
std::vector<unsigned int> offsets(s.size());
bool isContinue;
do
{
for(auto offset : offsets)
{
std::cout << s[offset];
}
std::cout << std::endl;
isContinue = false;
for(auto offset = offsets.rbegin(); offset != offsets.rend(); ++offset)
{
if(++*offset < s.size())
{
isContinue = true;
break;
}
*offset = 0;
}
}
while(isContinue);
The idea behind is like upcounting numbers (decimally): Once you've reached 9, you increment next digit. Alike, each offset in the vector stands for one loop variable, on 'overflow', increment next offset, and as soon as most significant offset 'overflows', we are done.
High performance variant (using goto, sparing one comparison and the condition variable):
std::vector<unsigned int> offsets(s.size());
NEXT:
for(auto offset : offsets)
{
std::cout << s[offset];
}
std::cout << std::endl;
for(auto offset = offsets.rbegin(); offset != offsets.rend(); ++offset)
{
if(++*offset < s.size())
goto NEXT;
*offset = 0;
}
There are a couple basic ways to do that looping.
The first is the explicit one: you need to use an array of indexes instead of a single variable for the loop index. Then at each step you increment the last index and when that gets past the limit you reset it and increment the previous one:
int n = str.size(); // Get rid of unsigned
std::vector<int> index(n);
for(;;) {
// Generate output
for (int i=0; i<n; i++) {
std::cout << str[index[i]];
}
std::cout << std::endl;
// Increment
int i = n-1; // start from last index
while (i>=0 && index[i] == n-1) {
// I-th index has reached the end of the string, flip over to 0
index[i] = 0;
--i;
}
if (i == -1) break; // all of them returned to 0... that's all, folks
index[i] += 1;
}
The second way is using recursion, for example with a function accepting the partial string being built as argument and that if this prefix is not complete loops over the string and calls itself passing an extended prefix:
std::function<void(const std::string&)> proc = [&](const std::string& prefix) {
if (prefix.size() == str.size()) {
// Prefix is complete, just output result
std::cout << prefix << std::endl;
} else {
// Extend the prefix and call yourself for the nested loops
for (int j=0; j<n; j++) {
proc(prefix + str[j]);
}
}
};
proc("");
The recursive approach is more compact but takes some time to become comfortable and it can be problematic in certain cases.
A different way avoiding nested loops be to use simple counting and math... it's easy to write a function that returns the n-th string you're looking for without looping over the previous ones...
for (int i=0,loops=pow(n, n); i<loops; i++){
std::string s = "";
int k = i;
for (int j=0; j<n; j++) {
s = str[k % n] + s;
k /= n;
}
std::cout << s << std::endl;
}
Let's fold all your N nested loops into one nested loop. First, we need N indices, which will be incremented properly:
class Multiindex
{
public:
Multiindex(int size, int last_) : idx(size,0), last(last_) {}
void inc()
{
for (int i = idx.size() - 1; i >= 0; --i) {
if (idx[i] == last - 1) {
idx[i] = 0;
if (i == 0) complete = true;
}
else {
++idx[i];
break;
}
}
}
const auto& getIdx() const { return idx; }
const auto isComplete() const { return complete; }
private:
std::vector<int> idx;
int last;
bool complete = false;
};
It's a minimal example of a multiindex class. You also may write a decrement method or use a vector of last indices, if you need different indices in your nested loop.
Now everything is ready to replace your nested loop:
std::string s;// From user
Multiindex midx(s.length(), s.length());
while (!midx.isComplete()) { // Your nested loop
const auto& idx = midx.getIdx();
for (int i = 0; i < idx.size(); ++i) { // Replacement for cout << s[i] << s[j] << ... << s[z] << endl;
std::cout << s[idx[i]];
}
std::cout << std::endl;
midx.inc();
}
Related
I already managed to make me of all the subsets but I do not know how to make their values add up and identify what I want. If someone could explain to me please.
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int n=3;
int arr[]={1,2,3};
int v;
int count = pow(2,n);
int acum=0;
cout << "Enter a value: ";
cin >> v;
for (int i = 0; i < count; i++) {
for (int j = 0; j < n; j++) {
if ((i & (1 << j)) != 0){
cout << arr[j] << " ";
}
}
cout << "\n";
}
return 0;
}
For your problem domain, is it valid to assume that all of the elements will be positive integers? If so, then you might want to consider using a "Dynamic Programming" (DP) solution (instead of the "Generate and Test" approach that you had begun).
The DP approach would solve your example as follows:
The initial task was to identify a subset whose sum is v=5.
DP makes one single pass through your arr[] data (my implementation's for i loop)
For the first element arr[0], that addition term (1) is either used or not used. If that 1 addition term is not used, then the problem arr[]={1,2,3},v=5 recursively becomes the sub-problem arr[]={2,3},v=5. But if that 1 term is used, then the problem arr[]={1,2,3},v=5 recursively becomes the sub-problem arr[]={2,3},v=4. We "memoize" this possibility by recording the used term (the 1 value) in memory at term[4] (term[] is a utility array that had been allocated for this very "DP memoization" purpose).
For the next element arr[1], again that term (2) is either used or not used. If that term is used, then the v=5 problem becomes a v=3 sub-problem, whereas the v=4 problem (if it exists) becomes a v=2 sub-problem. Again, any such sub-problem is recorded via "memoization" (in the same term[] utility array).
Finally, this pattern repeats for the final arr[2] element.
Once that single pass through arr[] is finished, the solution can be "back-traced" through the "memoization", by an iteration that starts at term[0].
This is a C++ implementation of the DP approach:
#include <iostream>
int main()
{
int n = 3;
int arr[n] = {1, 2, 3}; // All elements must be positive
int v;
std::cout << "Enter a value: ";
std::cin >> v;
int* term = new int[v];
for (int init = 0; init < v; init++) {
term[init] = 0;
}
for (int i = 0; i < n; i++) {
for (int before = 0; before < v; before++) {
if (term[before] == 0) {
int after = before + arr[i];
// This tests the "(if it exists)" condition in my verbal description:
if (after == v || (after < v && term[after] != 0)) {
// This assignment performs the "memoization":
term[before] = arr[i];
}
}
}
}
if (term[0] == 0) {
std::cout << "No such subset exists";
}
else {
int partialSum = 0;
while (partialSum < v) {
std::cout << term[partialSum];
partialSum += term[partialSum];
if (partialSum < v) {
std::cout << "+";
}
else {
std::cout << "=" << v;
}
}
}
delete[] term;
}
For context, I can't use anything that isn't taught in csc101 (what you learned may have been different) so I can't use things like vectors, structs, and classes. More context, I have an assignment which requests I have a function which takes an array numarray with random values, and removes the values from 20 to 40. As I understand it, the best way to do that is to make a new array and take the valid values from numarray and put them in a new array temparray. I tried implementing this the best way I could figure up, but it seems to only spit out a set number which is a long negative number over and over in a loop. I know it is this function because when not called I don't have a problem. The problem also doesn't occur if I comment out the while loop at the end of the function. I will first attach the function in question, and then the whole of the program for added context. Open to any criticism, but passing the class is my priority over elegance, and efficiency. If the professor wants something done a certain way, I must oblige. Thanks for your time.
The required function:
void Delete(int* numarray, int *temparray) {
int arrayindex = 0;
for (int index = 0; index < 100; index++) {
if (numarray[index] < 20 && numarray[index] > 40) {
temparray[arrayindex] = numarray[index];
} arrayindex++;
}
cout << arrayindex << endl;
cout << temparray[arrayindex] << endl;
while (arrayindex <! 0) {
cout << temparray[arrayindex - 1] << endl;
}
}
The whole project:
#include <iostream>
#include <fstream>
#include <time.h>
#include <stdlib.h>
#include <cstddef>
#include <array>
using namespace std;
ofstream randomData;
ifstream inputrandomData;
void randomgenerator();
void read(int *numarray);
void printArray(int *numarray);
void searchArray(int* numarray);
void Delete(int* numarray, int* temparray);
void randomgenerator() {
srand(time(0));
randomData.open("randomData.txt");
for (int counter = 0; counter < 100; counter++) {
randomData << rand() % 100+1 << endl;
}
randomData.close();
}
void read(int *numarray) {
inputrandomData.open("randomData.txt");
for (int i = 0; i < 100; i++) {
inputrandomData >> numarray[i];
}
inputrandomData.close();
}
void printArray(int *numarray) {
for (int index = 0; index < 100; index++) {
cout << numarray[index] << endl;
}
}
void searchArray(int* numarray) {
int searchedArray[6] = {};
for (int index=0; index < 100; index++) {
if (numarray[index] > searchedArray[0]) {
searchedArray[0] = numarray[index];
searchedArray[1] = index;
}
}
for (int index = 0; index < 100; index++) {
if (numarray[index] > searchedArray[2] && numarray[index] < searchedArray[0]) {
searchedArray[2] = numarray[index];
searchedArray[3] = index;
}
}
for (int index = 0; index < 100; index++) {
if (numarray[index] > searchedArray[4] && numarray[index] < searchedArray[2]) {
searchedArray[4] = numarray[index];
searchedArray[5] = index;
}
}
cout << "Largest Number: " << searchedArray[0] << " " << "Index: " << searchedArray[1] << endl;
cout << "Second Largest Number: " << searchedArray[2] << " " << "Index: " << searchedArray[3] << endl;
cout << "Third Largest Number: " << searchedArray[4] << " " << "Index: " << searchedArray[5] << endl;
}
void Delete(int* numarray, int *temparray) {
int arrayindex = 0;
for (int index = 0; index < 100; index++) {
if (numarray[index] < 20 && numarray[index] > 40) {
temparray[arrayindex] = numarray[index];
} arrayindex++;
}
cout << arrayindex << endl;
cout << temparray[arrayindex] << endl;
while (arrayindex <! 0) {
cout << temparray[arrayindex - 1] << endl;
}
}
int main() {
int numarray[100] = {};
int temparray[100] = {};
randomgenerator();
read(numarray);
printArray(numarray);
searchArray(numarray);
Delete(numarray, temparray);
return 0;
}
Here was the solution I was prompted to come up with. There were a couple logical flaws.
First, my conditional would never be true as I used the && operator which means the number would have to be lower than 20 AND greater than 40. Changed that to || operator to check for one or the other. Then, as stated in the comments, I had been overthinking it by creating another array. You have to have two different index counters in order to read from the original data set, and to write the new data set in behind it. Now, when ran, the numarray takes values at the numarray[arrayindex] which is only incremented when the conditional is called, and reads from numarray[index] which increments on every for loop. Here is the edited function below:
void Delete(int* numarray) {
int arrayindex = 0;
for (int index = 0; index < 100; index++) {
if (numarray[index] < 20 || numarray[index] > 40) {
numarray[arrayindex] = numarray[index];
arrayindex++;
}
}
cout << arrayindex << endl;
for (int newindex = 0; newindex < arrayindex; newindex++) {
cout << numarray[newindex] << endl;
}
}
I removed temparray from the program entirely. Thanks for the help.
You can break up the problem into many pieces at first so that it is easier to program and understand. If you're struggling, keep splitting up the task into smaller simpler functions, like this:
// remove a range of values from arr
void remove_range(int *arr, int size, int from, int to) {
for (int r = from; r <= to; r++) {
remove_all(arr, size, r);
}
}
// remove all of a single value from arr
void remove_all(int *arr, int size, int value) {
for (int i = 0; i < size; i++) {
if (arr[i] == value) {
remove_one(arr, size, value);
}
}
}
// remove the first occurrence of a value from arr
void remove_one(int *arr, int size, int value) {
for (int i = 0; i < size; i++) {
if (arr[i] == value) {
remove_i(arr, size, value);
}
}
}
// remove the value at an index of arr by shifting all the entries after it left one
// and putting a 0 at the end in case this is the first removal
void remove_i(int *arr, int size, int i) {
for (; i < size - 1; i++) {
arr[i] = arr[i + 1];
}
arr[i] = 0;
}
If I'm understanding your project correctly, you have the following main objectives:
Without using std::vector or other classes/structs, copy an array into another
The copied-to array must not contain values from 20-40 (assuming inclusive)
With that in mind, there are some other things you may want to keep in mind. For example, does speed or memory matter more?
If speed matters more, you can create an array (named copy_to) with equal size of copy_from array. Then, just test every value in copy_from to make sure it's not within [20, 40] before copying it to copy_to. However, If memory management matters more, not only would I do everything from the "speed" method, but I would also keep track of how many elements are being added to copy_to. After they are copied, make a new array (copy_to_final) of the exact size needed, copy copy_to to copy_to_final, and delete copy_to.
Here's what the code would look like for the speed method:
int* make_prejudice_array(int[] copy_from, size_t size)
{
// Make array to store new values in
int* copy_to = new int[size];
size_t copy_to_size = 0;
// Copy valid values into 'copy_to'
for (size_t i = 0; i < size; ++i)
{
if (copy_from[i] < 20 || copy_from[i] > 40)
{
copy_to[copy_to_size] = copy_from[i];
copy_to_size++;
}
}
return copy_to;
}
And, for the memory management way, just a small addition:
int* make_prejudice_array(int[] copy_from, size_t size)
{
int* copy_to = new int[size];
size_t copy_to_size = 0;
for (size_t i = 0; i < size; ++i)
{
if (copy_from[i] < 20 || copy_from[i] > 40)
{
copy_to[copy_to_size] = copy_from[i];
copy_to_size++;
}
}
// Make new array to hold the exact number of elements needed
int* copy_to_final = new int[copy_to_size];
for (size_t i = 0; i < copy_to_size; ++i)
copy_to_final[i] = copy_to[i];
// Don't forget to delete 'copy_to' to prevent a mem leak
delete[] copy_to;
copy_to = nullptr;
return copy_to_final;
}
If I missed something from your question. Let me know and I'll do my best to incorporate it. Hope that helps!
I am trying to implement the algorithm RLE with simple input like:
ddddddddddhhhhhhhhhhhhhhhttttttttttttt
code:
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
int main() {
vector<char> read;
ifstream file;
file.open("file.txt");
if (!file) {
cout << "Unable to open";
}
char v;
while(file>>v) {
read.push_back(v);
}
char x;
int count=0;
for(int i=0; i<read.size(); i++) {
x = read[i];
if(x != read[++i]) {
cout << x << "1";
}
while(x == read[++i]) {
count++;
}
cout << x << count;
count = 0;
}
return 0;
}
The output I am getting is:
d9d1h12h1t10t1
Please help me with the code.
Update: I have updated the question as I have realized few things.
Plus: This code produced no output, is there anything wrong which I am doing wrong?
char o;
char n;
int count=0;
for(int i=0; i<read.size(); i++) {
o = read[i];
n = read[++i];
while(o == n) {
count++;
}
cout << o << count;
if(o != n) {
cout << o << "1";
} count = 0;
}
return 0;
This loop:
char x;
int count=0;
for(int i=0; i<read.size(); i++) {
int j=i;
x = read[i];
if(x != read[++j]) {
cout << x << "1";
}
while(x == read[++j]) {
count++;
}
cout << x << count;
}
Has several errors. First, you should use two indices, i and j. i is going through each element of read, but then j is iterating through a subsequence too. What you want is to go through each element only once, and in each case either print or increase the count. However having a for loop and moving the index inside too is not a very good practice, is rather error-prone. Also you have to cout statements that are do not run at the right time (you don't wan to print something on every iteration, only when the character changes). You could do it with a while loop, or using a simpler structure like:
// If there are no characters finish
if (read.empty()) {
return 0;
}
// Get the first character
char lastChar = read[0];
int count = 1; // We have counted one character for now
// Go through each character (note start from 1 instead of 0)
for(int i = 1; i < read.size(); i++) {
// Get the next char
char newChar = read[i];
// If it is different, print the current count and reset the counter
if (lastChar != newChar) {
cout << lastChar << count;
count = 1;
lastChar = newChar;
} else { // Else increase the counter
count++;
}
}
// Print the last one
cout << lastChar << count;
return 0;
I was trying to solve the 3 sum problem in cpp.
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int size = nums.size();
vector<vector<int>> result;
for (int i = 0; i < size - 2; ++i) {
for (int j = i + 1; j < size - 1; ++j) {
for (int k = j + 1; k < size; ++k) {
if (sumToZero(i, j, k, nums)) {
vector<int> newComb = vectorify(i, j, k, nums);
//printComb(newComb);
if (!exist(newComb, result)) {
//cout << "not exist" << endl;
result.push_back(newComb);
} else {
//cout << "exist" << endl;
}
}
}
}
}
return result;
}
bool sumToZero(int i, int j, int k, vector<int>& nums) {
return nums[i] + nums[j] + nums[k] == 0;
}
vector<int> vectorify(int i, int j, int k, vector<int>& nums) {
vector<int> result;
result.push_back(nums[i]);
result.push_back(nums[j]);
result.push_back(nums[k]);
return result;
}
void printComb(vector<int>& input) {
cout << input[0] << input[1] << input[2] << endl;
}
bool isSameComb(vector<int>& a, vector<int> b) {
for (int i = 0; i < b.size(); ++i) {
if (a[0] == b[i]) {
b.erase(b.begin() + i);
}
}
for (int i = 0; i < b.size(); ++i) {
if (a[1] == b[i]) {
b.erase(b.begin() + i);
}
}
for (int i = 0; i < b.size(); ++i) {
if (a[2] == b[i]) {
b.erase(b.begin() + i);
}
}
return b.empty();
}
bool exist(vector<int>& niddle, vector<vector<int>>& haystack) {
int size = haystack.size();
for (int i = 0; i < size; ++i) {
if (isSameComb(niddle, haystack[i])) {
return true;
}
}
return false;
}
};
However, this solution exceeded the time limit. I cannot think of the source of extra complexity. Can someone help me point out where am I doing extra computation?
You can be in O(n²) with something like:
std::vector<std::vector<int>> threeSum(std::vector<int>& nums) {
std::sort(nums.begin(), nums.end());
std::vector<std::vector<int>> res;
for (auto it = nums.begin(); it != nums.end(); ++it) {
auto left = it + 1;
auto right = nums.rbegin();
while (left < right.base()) {
auto sum = *it + *left + *right;
if (sum < 0) {
++left;
} else if (sum > 0) {
++right;
} else {
res.push_back({*it, *left, *right});
std::cout << *it << " " << *left << " " << *right << std::endl;
++left;
++right;
}
}
}
return res;
}
Demo
I let duplicate handling as exercise.
The source of extra complexity is the third loop, which brings time complexity of your code to O(n3).
Key observation here is that once you have two numbers, the third number is fixed, so you do not need to loop around to find it: use hash table to see if it's there or not in O(1). For example, if your first loop looks at value 56 and your second loop looks at value -96, the third value must be 40 in order to yield zero total.
If the range of numbers is reasonably small (say, -10000..10000) you can use an array instead.
This would bring time complexity to O(n2), which should be a noticeable improvement on timing.
A couple of possibilities:
First, construct a hash table of all entries in the vector up front, then remove the third loop. Inside the second loop, simply check whether -nums[i] - nums[j] exists in the hash table. That should bring your time complexity from O(n3) back to something closer to O(n2).
Second, function calls aren't free though an optimiser can sometimes improve that considerably. There's no performance reason why you should be calling a function to check if three numbers add to zero so you could replace:
if (sumToZero(i, j, k, nums)) {
with:
if (nums[i] + nums[j] == -nums[k]) {
Of course, this is rendered moot if you adopt the first suggestion.
Third, don't check and insert the possible result every time you get one. Just add it to the vector no matter what. Then, at the end, sort the vector and remove any duplicates. That should hopefully speed things up a bit as well.
Fourth, there's quite possibly a performance hit for using a vector for the potential result when an int[3] would do just as well. Vectors are ideal if you need something with a variable size but, if both the minimum and maximum size of an array-type collection is always going to be a fixed value, raw arrays are fine.
But perhaps the most important advice is measure, don't guess!
Make sure that, after each attempted optimisation, you test to see whether it had a detrimental, negligible, or beneficial effect. A test suite of various data sets, and automating the process, will make this much easier. But, even if you have to do it manually, do so - you can't improve what you can't measure.
Here is my solution that finds all unique triplets in O(n^2) run-time.
class Solution {
public: vector<vector<int>> threeSum(vector<int>& nums) {
int len = nums.size();
if(len<3) return {};
sort(nums.begin(), nums.end());
vector<vector<int>> retVector;
int target, begin, end;
int i=0;
while(i < len - 2)
{
int dup; // to find duplicates entries
target = -nums[i];
begin = i + 1; end = len - 1;
while (begin < end)
{
if (nums[begin] + nums[end] < target) begin++;
else if (nums[begin] + nums[end] > target) end--;
else
{
retVector.push_back({nums[i], nums[begin], nums[end]});
// its time to remove duplicates
dup=nums[begin];
do begin++; while(nums[begin] == dup); // removing from front
dup=nums[end];
do end--; while(nums[end] == dup); // removing from back
}
}
dup=nums[i];
do i++; while(nums[i] == dup) ; // removing all ertries same as nums[i]
}
return retVector;
}
};
I have to write a C++ code that finds the median and mode of an array. I'm told that it's much easier to find the mode of an array AFTER the numbers have been sorted. I sorted the function but still cannot find the mode.
int counter = 0;
for (int pass = 0; pass < size - 1; pass++)
for (int count = pass + 1; count < size; count++) {
if (array [count] == array [pass])
counter++;
cout << "The mode is: " << counter << endl;
If the array has been sorted already, you can count the occurrences of a number at once. Then just save the number that has biggest occurrences. And you can find out the mode in only one for-loop.
Otherwise, you'll have to do more than one for-loops.
See a details example at the link below
Find-the-Mode-of-a-Set-of-Numbers
Here is the code,
int number = array[0];
int mode = number;
int count = 1;
int countMode = 1;
for (int i=1; i<size; i++)
{
if (array[i] == number)
{ // count occurrences of the current number
++count;
}
else
{ // now this is a different number
if (count > countMode)
{
countMode = count; // mode is the biggest ocurrences
mode = number;
}
count = 1; // reset count for the new number
number = array[i];
}
}
cout << "mode : " << mode << endl;
One way is that you can use Run Length encoding. In Run Length encoding, representation would be like; (Item, Its frequency).
While doing so, keep track of the maximum frequency and Item. This will give you the mode once you complete the Run Length.
for example:
1 1 2 2 2 3 3 4 5
It run length encoding would be
{1, 2}, {2, 3}, {3, 2}, {4, 1}, {5, 1}
It needs O(n) space.
This is how I did it, my solution will take a sorted vector as input. It has O(n) time complexity and can work with the case where there are more than 1 "mode" number in the vector.
void findMode(vector<double> data) {
double biggestMode = 1;
vector<double> mode, numbers;
numbers.push_back(data.at(0));
mode.push_back(1);
int count = 0;
for (int i = 1; i < data.size(); i++) {
if (data.at(i) == numbers.at(count)) {
mode.at(count)++;
}
else {
if (biggestMode < mode.at(count)) {
biggestMode = mode.at(count);
}
count++;
mode.push_back(1);
numbers.push_back(data.at(i));
}
}
for (int i = 0; i < mode.size(); i++) {
if (mode.at(i) == biggestMode)
cout << numbers.at(i) << " ";
}
cout << endl;
}
Here is the code snippet:
int number = array[0];
int mode = number;
int count = 1;
int countMode = 1;
for (int i=1; i<size; i++)
{
if (array[i] == number)
{
count++;
}
else
{
if (count > countMode)
{
countMode = count;
mode = number;
}
count = 1;
number = array[i];
}
}
cout << "mode : " << mode << endl;
There is an old adage that states "If you put 10 programmers in a room and give them the same program to code you will get 12 different results", hence my version of answering your question. It may not be as fast (I'm planning on testing it's speed versus some of the other suggestions) but I feel it is easy to understand.
#include <iostream>
using namespace std;
int main ()
{
short z[10];
short maxCount = 0, curCount = 0, cur = 0, most = 0;
for (int i = 0; i < 10; i++)
{
cout << "Enter a number: " << endl;
cin >> z[i];
}
for (int i = 0; i < 10; i++)
{
cur = z[i];
for (int a = i; a < 10; a++)
{
if (cur == z[a])
{
curCount++;
cur = z[a];
}
if (curCount > maxCount)
{
maxCount = curCount;
most = z[a];
}
}
curCount = 0;
}
cout << "the mode is : " << maxCount << ", the number is: " << most << endl;
}
int number = array[0];
int mode = number;
int count = 1;
int countMode = 1;
for (int i=1; i<size; i++)
{
if (array[i] == number)
{ // count occurrences of the current number
++count;
}
else
{ // now this is a different number
count = 1; // reset count for the new number
number = array[i];
}
if (count > countMode) {
countMode = count;
mode = number;
}
}
cout << "mode : " << mode << endl;
While Diedrei's answer is close, several people have pointed out some shortcomings such as if the mode is defined by the last numbers of the sorted array (1,2,3,3,4,4,4 would return 3 as the mode). Also, depending on the requirements on how to handle multiple modes, there will be different solutions.
This solution does several things:
Solves the issue of the mode being at the end of the array
If there are multiple modes (more than 1 number has the same number of occurrences with a count > 1), returns the smallest number as the mode
Returns -1 if there is no mode (each number only occurs once)
int number = array[0];
int mode = number;
int count = 1;
int countMode = 1;
for (int i=1; i<size; i++)
{
if (array[i] == number)
{ // increment the count of occurrences for the current number
++count;
if (count > countMode)
{
countMode = count; // this number now has the most occurrences
mode = number; // this number is now the mode
}
}
else
{ // now this is a different number
count = 1; // reset count for the new number
number = array[i]; // set the new number
}
}
if (countMode == 1) {
mode = -1; // set the mode to -1 if each number in the array occur only once
}
cout << "mode : " << mode << endl;
The "mode" is the value that occurs most often. If no number is repeated, then there is no mode for the list.
So there would be no benefit to sorting if you needed to know the "mode".
Are you sure you are not referring to the median? The median is the middle number in a set.
If you have 1,2,3,4,5 the Median (middle number) is the (total_number)/2) rounded up if it is odd, 2.5 -> 3 and our median would be 3. you can only really calculate the median if your numbers are sorted.
If you have an even number in a set 1,2,3,4,5,6
your mode is slots 3,4 (coincidentally also, 3,4)
(total_number)/2 slot and (total_number)/2 + 1 slot, for any even array of numbers.
http://www.purplemath.com/modules/meanmode.htm
This code should give you the mode. If there are equal number of two different numbers, it will output the first of such.
int count = 1, mode = 0, m = 0, i = 1;
size_t sz = sizeof(array)/sizeof(*array);
while(i != sz+1) {
if(array[i-1] != array[i]) {
if(count > m) {
mode = array[i-1];
m = count;
count = 1;
}
}
else
++count;
++i;
}
std::cout << "mode: " << mode << std::endl;
This code finds the mode in C++:
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int i,j,k=0,n,repeat_max=0,cn=0;
int array1[50],mode[50],count[50]={0},c[50];
cout<<"\n inter count:\t";
cin>>n;
cout<<"\n";
for(i=0;i<n;i++)
cin>>array1[i];
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(array1[i]==array1[j])
{
count[i]++;
if(count[i]>=repeat_max)
{
repeat_max=count[i];
mode[k++]=array1[i];
}
}
}
}
cout<<"\n================\n";
for(i=1;i<k;i++)
cout<<"\t mode[i]="<<mode[i]<<"\n";
cout<<"\t\n\nrepeat array:"<<repeat_max;
return 0;
}
I did it this way:
int main()
{
int mode,modecount2,modecount1;
bool is_nomode=false;
vector<int> numbers = { 15,43,25,25,25,25,16,14,93,93,58,14,55,55,55,64,14,43,14,25,15,56,78,13,15,29,14,14,16 };
sort(numbers);
//If you uncomment the following part, you can see the sorted list of above numbers
//for (int i = 0; i < numbers.size(); ++i) std::cout << numbers[i] << '\n';
//keep_window_open();
mode = numbers[0];
modecount1 = 0;
modecount2 = 1; //Obviously any number exists at least once!
for (int i = 1; i < numbers.size(); ++i) {
if(numbers[i]==numbers[i-1]) ++modecount2;
else {
if (modecount2 > modecount1) {
mode = numbers[i - 1];
modecount1 = modecount2;
}
else if (i != 1 && modecount2 == modecount1) { std::cout << "No mode!\n"; is_nomode = true; break; }
modecount2 = 1;
}
}
if(!is_nomode) std::cout << "Mode of these numbers is: " << mode << std::endl;
keep_window_open();
Also you can add another 25 to the list of numbers and see what happens if two numbers have the same occurrence!
I hope it helps.
This code uses "map" to find out the MODE from the given array.
It assumes the array is already sorted.
int findMode(int * arr, int arraySize)
{
map<int, int> modeMap;
for (int i = 0; i < arraySize; ++i) {
++modeMap[arr[i]];
}
auto x = std::max_element(modeMap.begin(), modeMap.end(),
[](const pair<int, int>& a, const pair<int, int>& b) {
return a.second < b.second; });
return x->first;
}
This is the code I've written for sorted vector
void print_mode(vector<int>& input)
{
int mode=0, count = 0;
int current_number = input[0];
int mode_number = current_number;
for (int i=0; i < input.size(); i++)
{
if (current_number == input[i])//check if the number is the same
{
count++;
}
else //this fuction works when the value are no longer the same and
//this is when it updates the mode value
{
if (count > mode)//update mode value
{
mode = count;
mode_number = current_number;
}
count = 1;// it is not reset back to zero because when it the program detect a
//different number it doesn't count it so this is to solve that issue
}
if (i == input.size() - 1)// this function before it doesn't work when the largest value
//is mode so I added this if state to solve it
{
if (count > mode)
{
mode = count;
mode_number = current_number;
}
}
current_number = input[i];//prepare for next value
}
cout << mode_number << " is the mode number and it is repeated " << mode << " times" << endl;
}
1. Finding the mode without sorting
I'm told that it's much easier to find the mode of an array AFTER the numbers have been sorted
I'm not so sure.
std::vector<std::pair<int, unsigned>> mode(const std::vector<int> &v)
{
if (v.empty())
return {};
std::unordered_set<int> seen;
unsigned max_count(0);
std::vector<std::pair<int, unsigned>> ret;
for (auto i(v.begin()); i != v.end(); ++i)
if (seen.find(*i) == seen.end())
{
const auto count(std::count(i, v.end(), *i));
if (count > max_count)
{
max_count = count;
ret = {{*i, max_count}};
}
else if (count == max_count)
ret.emplace_back(*i, max_count);
seen.insert(*i);
}
return ret;
}
The algorithm
uses a hash table (seen) to skip already seen numbers;
doesn't need a copy of the input vector;
only requires a container with forward iterator support.
Also note that for small input vectors the function can be simplified removing the hash table.
You can play with the code here.
2. Finding the mode sorting
std::vector<std::pair<int, unsigned>> mode(std::vector<int> v)
{
if (v.empty())
return {};
std::sort(v.begin(), v.end());
auto current(*v.begin());
unsigned count(1), max_count(1);
std::vector<std::pair<int, unsigned>> ret({{current, 1}});
for (auto i(std::next(v.begin())); i != v.end(); ++i)
{
if (*i == current)
++count;
else
{
count = 1;
current = *i;
}
if (count > max_count)
{
max_count = count;
ret = {{current, max_count}};
}
else if (count == max_count)
ret.emplace_back(current, max_count);
}
return ret;
}
We assume an unsorted input vector, so the function works on a copy of the original vector that is sorted and processed.
If the original vector is already sorted, the input argument can be passed by reference and the std::sort call can be removed.
You can play with the code here.
Performance
Performance depends on multiple factor (size of the input vector, distribution of values...).
E.g. if the range of the input integers is small algorithm 1 is faster than algorithm 2.
You can experiment here.
I know the question is old, but here is a clean and short code that calculates statistical mode:
std::sort(vector.begin(), vector.end());
int mode = vector[0], count = 0, countMode = 1;
int last = mode;
for (int i = 1; i < vector.size(); ++i)
{
if (vector[i] == mode) ++countMode;
else
{
if (last != vector[i]) count = 0;
++count;
}
if (count > countMode)
{
mode = vector[i];
countMode = count;
count = 0;
}
last = vector[i];
}
int findModa(int *arr, int n) {
int count=1;
int countmax=0;
int current = arr[0];
int moda = 0;
for (int i=1; i<n; i++) {
if(arr[i] == curr) {
count++;
}
else if (count>countmax) {
countmax=count;
count=1;
moda=arr[i-1];
current=arr[i];
}
current=arr[i];
}
return moda;
}