Print front and back from an array c++ - c++

how can i print from array once from back and once from front c++?
for examble:
char c[] = { 'A','B','C','D' };
for (int i = 0; i < size(arr); i++)
{
cout << c[i];
}
the output will be ABCD
but the output that i want should be ADBC
print one from front and one from end c[0],c[3],c[1],c[2]

You can use. Here we iterate for only half number of times the size of the array. Note that this assumes you have even number of elements in the array.
int main()
{
char c[] = { 'A','B','C','D','E' };
std::size_t len = std::size(c);
//---------------------v------------->divide by 2 so that we iterate only half the size times
for (int i = 0; i < len/2; i++)
{
std::cout << c[i]<<c[len - i - 1];
}
if (len % 2) {//in case we have odd number of elements
std::cout << c[len/2];
}
}
Working demo

Related

filling 2d char array and accessing each element

It's my first question in stack overflow so if there is some mistakes sorry about that. I'm trying to fill a 2d char array and then access each letter. I complied my code, there is no error but when I try to run it doesn't work. Here it's my code.
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
int main() {
char ch[] = "Welcome text in a separate line.";
char strWords[5][7];
int counter = 0;
int a = 0;
for (int i = 0; i < sizeof(ch); i++) {
if (ch[i] == ' ') {
strWords[counter][a] = '\0';
counter++;
a = 0;
}
else
{
strWords[counter][a] += ch[i];
a++;
}
}
for (int i = 0; i <= 5; i++) {
for (int a = 0; a <= 7; a++) {
cout << strWords[i][a] << " ";
}
}
return 0;
}
A few things wrong with your code
int main() {
char ch[] = "Welcome text in a separate line.";
// char strWords[5][7]; <<<=== i would change to be larger that you need, just in case
char strWords[20][20];
int counter = 0;
int a = 0;
for (int i = 0; i < strlen(ch); i++) { // sizeof is wrong, you need strlen
if (ch[i] == ' ') {
strWords[counter][a] = '\0';
counter++;
a = 0;
}
else
{
//strWords[counter][a] += ch[i];
strWords[counter][a] = ch[i]; // you do not need to try to concatenate, you are already walking down the buffer with 'a'
a++;
}
}
for (int i = 0; i < counter; i++) { // use 'counter' as it has the number of lines
// since you 0 terminated the string you do not need to walk character by character
cout << strWords[i] << " ";
}
return 0;
}
You are also not detecting and terminating the last word (since there is no space after it). I will leave that to you. The code I show does not print the word 'line.'
You should really have tests to make sure you do not overflow the length or number of words.
Plus you should ideally use std::string and std::vector
Note - if, for experimentation, you do want to walk through char by char to output the strings you should look for the terminating '0' character and exit the inner loop

Int to Char array(part sums)

I have problem with "tab" output. My program is going to show part sums.
I want to save those part sums in tab array but it shows only first sum.
here is code I wrote:
const char numbers[] = { "1 2 3 4" };
cout << numbers << endl;
for (int i = 0; i < strlen(numbers); ++i)
{
if (numbers[i] != ' ') cout << numbers[i] << endl;
}
int sum = 0;
char tab[20];
for (int i = 0; i < strlen(numbers); ++i){
if (numbers[i] != ' ') {
sum += atoi(&numbers[i]);
_itoa_s(sum,&tab[i],sizeof(tab),10);
}
}
cout << tab;
_getch();
return 0;
How I can make it to show proper part sums like: 1 3 6 10
sizeof shows the size of the array in bytes, not the number of elements in the array.
Something like this will give you the number of elements:
int num_element = sizeof(numbers)/sizeof(numbers[0]);
Or a full solution:
const char numbers[] = { "1 2 3 4" };
int num_elements = sizeof(numbers)/sizeof(numbers[0]);
cout << numbers << endl;
for (int i = 0; i < num_elements; ++i)
{
if (numbers[i] != ' ') cout << numbers[i] << endl;
}
int sum = 0;
char tab[20];
for (int i = 0; i < num_elements; ++i){
if (numbers[i] != ' ') {
sum += atoi(&numbers[i]);
_itoa_s(sum,&tab[i],sizeof(tab),10);
}
}
cout << tab;
_getch();
return 0;
Although the above should work after replacing num_element into your for loops, I suggest you looking into a std::array or std::vector
Your code has several problems. The first one is that function atoi will return an error because is will consider all string starting from &numbers[i] till the terminating zero. The other problem is that this in expression
_itoa_s(sum,&tab[i],sizeof(tab),10);
using tab[i] is incorrect.
Try the following code.
#include <iostream>
#include <cstring>
#include <cctype>
#include <cstdio>
//...
const char numbers[] = { "1 2 3 4" };
char tab[20];
char *p = tab;
int sum = 0;
for ( size_t i = 0, n = std::strlen( numbers ); i < n; i++ )
{
if ( std::isdigit( numbers[i] ) )
{
sum += numbers[i] - '0';
p += std::sprintf( p, "%d ", sum );
}
}
std::cout << tab << std::endl;
At least I got output
1 3 6 10
Also it would be better to use std::istringstream instead of the for loop where you are extracting digits.
You are not retrieving the size of your arrays here.
Use SIZEOF_ARRAY to get the size of numbers in C.
But you tagged C++, so consider using std::array<> instead of a C-style array (it will expose the size of the array for you)
Firstly, cout << tab; prints only the first element.
Secondly, instead of writing the result to tab[i], create int cnt = 0; _itoa_s(sum,&tab[cnt],sizeof(tab),10); cnt++ By that way, you won't have empty characters in you tab array.
Thirdly, you can keep int tab[20], rather than to keep in char tab[].
Forthly, int num_elem = sizeof(numbers)/sizeof(numbers[0]);(as said above).

least frequent common number from a int array

I have to find least common number from an int array , I have written code but it is not working properly ,
Here is my logic,
1. sort the array
2. get min common counter updated
3. get if all are unique
and the code below,
static int min_loc ; //minimum value location
static int min_cnt ;
int all_uniqFlag = true;
void leastCommon(int data[],int n)
{
int rcount = 0; //Repeated number counter
int mcount = n; // minimum repetetion counter;
// The array is already sorted we need to only find the least common value.
for(int i = 0 ; i < n-1 ; i++)
{
//Case A : 1 1 2 2 2 3 3 3 3 4 5 5 5 5 : result should be 4
//Case B : 1 2 3 4 5 6 7 (All unique number and common values so all values should be printed
// and )
//Case C : 1 1 2 2 3 3 4 4 (all numbers have same frequency so need to display all )
cout << "data[i] : " << data[i] << " data[i+1] : " << data[i+1] << "i = " << i << endl;
if(data[i] != data[i+1])
{
//mcount = 0;
//min_loc = i;
//return;
}
if(data[i] == data[i+1])
{
all_uniqFlag = false;
rcount++;
}
else if(rcount < mcount)
{
mcount = rcount;
min_loc = i ;//data[i];
}
}
min_cnt = mcount;
}
As mentioned in the comment only Case B works and Case A and C is not working could you help me fix the issue ?
scan through the list
compare each element in the list with the last element in the out array
If the element matches, then increment its count by 1
If the element doesn't match then add the new element into out
array and increment index by 1
Once the scan is done, the out array will have all the distinct elementsout[][0] and their frequencies out[][1]
Scan through the frequency list (out[][1]) to find the lowest frequency
Finally do another scan through the element list out[][0] and print elements whose frequency matches with the lowest frequency
.
#include<stdio.h>
#include<stdlib.h>
#define N 8
int main()
{
//int data[N]={1,2,3,4,5,6,7};
int data[N]={1,1,2,2,3,3,4,4};
//int data[N]={1,1,2,2,2,3,3,3,3,4,5,5,5,5};
int out[N][2];
int i=0,index=0;
for(i=0;i<N;i++)
{
out[i][0]=0;
out[i][1]=0;
}
out[0][0] = data[0];
out[0][1]=1;
for(i=1;i<N;i++)
{
if(data[i] != out[index][0])
{
index++;
out[index][0] = data[i];
out[index][1] = 1;
}
else
{
out[index][1]++;
}
}
int min=65536;
for(i=0;i<N;i++)
{
if(out[i][1] == 0)
{
break;
}
if(out[i][1] < min)
{
min = out[i][1];
}
}
for(i=0;i<N;i++)
{
if(out[i][1] == min)
{
printf("%d\t",out[i][0]);
}
}
printf("\n");
}
You can use a map for this:
#include <string>
#include <map>
#include <iostream>
typedef std::map<int, int> Counter;
void leastCommon(int data[],int n) {
Counter counter;
int min = n;
for (int i = 0; i < n; i++)
counter[data[i]]++;
for (Counter::iterator it = counter.begin(); it != counter.end(); it++) {
if (min > it->second) min = it->second;
}
for (int i = 0; i < n; i++) {
if (counter[data[i]] == min) {
std::cout << data[i] << std::endl;
counter[data[i]]++;
}
}
}
int main() {
int data[] = {1, 1,3,4,4,2,4,3,2};
leastCommon(data, 9);
return 0;
}
Approach is-
select 1st element from the sorted array, and while consecutive elements to it are same, store them in output[] until the loop breaks
store the frequency of element in leastFrequency
select next element, check with its consecutive ones and store them in same output[] until the loop breaks
check frequency of this with the leastFrequency
if same, do nothing (let these be added in the output[])
if less, clear output[] and store the element same no. of times
if more, change the effective output[] length to previous length before iterating for this element
similarly iterate for all distinct elements and finally get the result from output[] from 0 to effective length
void leastCommon(int data[], int len) {
if ( len > 0) {
int output[] = new int[len];
int outlen = 0; // stores the size of useful-output array
int leastFrequency = len; // stores the lowest frequency of elements
int i=0;
int now = data[i];
while (i < len) {
int num = now;
int count = 0;
do {
output[outlen] = now;
outlen++;
count++;
if((++i == len)){
break;
}
now = data[i];
} while (num == now); // while now and next are same it adds them to output[]
if (i - count == 0) { // avoids copy of same values to output[] for 1st iteration
leastFrequency = count;
} else if (count < leastFrequency) { // if count for the element is less than the current minimum then re-creates the output[]
leastFrequency = count;
output = new int[len];
outlen = 0;
for (; outlen < leastFrequency; outlen++) {
output[outlen] = num; // populates the output[] with lower frequent element, to its count
}
} else if (count > leastFrequency) {
outlen -= count; // marks outlen to its same frequent numbers, i.e., discarding higher frequency values from output[]
}
}
//for(int j = 0; j < outlen; j++) {
// print output[] to console
//}
}
}
Plz suggest for improvements.

copy one array to another without duplicates C++

The problem is that, I have an array of 10 integers, having some duplicates. The task is to copy this array to another array of same size, but without duplicate values. That is, read one element from array1, compare it with all the elements in array2, if it's already in array2, just skip it or print that it's already in array2, go to second element of array1, and repeat the process.
Now, I've tried this but don't know where's the problem:
#include <iostream>
using namespace std;
int main()
{
int temp;
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[11] = {0};
for(int i = 1; i <= 10; i++)
{
temp = array1[i-1];
for(int j = 1; j <= 10; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
i++;
break;
}
}
array2[i] = array1[i-1];
}
for(int k = 1; k <= 10; k++)
cout << array2[k] << " " << endl;
system("pause");
}
array1 has 10 elements and array2 has 11, so right away the requirements haven't been met. Presumably, having 11 elements was a workaround for using incorrect index values in the for loops; the index should run from 0 to 9, not from 1 to 10.
When you add an element to the second array, you should only check it value against the elements that have already been added, not against the values in the entire array.
Finally, there's an underspecification. Once you've eliminated duplicates, you have fewer than 10 elements; array2 has 10 elements; what values should the extra elements have?
std::unique_copy is your friend:
http://en.cppreference.com/w/cpp/algorithm/unique_copy
remember to sort the source array first
In C++, break immediately ends one loop structure, and starts execution immediately after it. Thus, the line array2[i] = array1[i-1]; executes redardless of whether the inner for loop finds a duplicate. One solution is to set a variable indicating that the value is a duplicate:
int main() {
int temp;
bool isDuplicate; //added this line
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[11] = {0};
for(int i = 1; i <= 10; i++)
{
temp = array1[i-1];
isDuplicate=false;//added this line
for(int j = 1; j <= 10; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
i++;
isDuplicate=true; //added this line
break;
}
}
if(!isDuplicate) //added this line
array2[i] = array1[i-1];
}
for(int k = 1; k <= 10; k++)
cout << array2[k] << " " << endl; system("pause"); }
Alternatively (though many programmers would disagree with this practice) you could use a goto statement instead of a break statement:
int main()
{
int temp;
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[11] = {0};
for(int i = 1; i <= 10; i++)
{
temp = array1[i-1];
for(int j = 1; j <= 10; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
i++;
goto duplicate; //added this line
}
}
array2[i] = array1[i-1];
//added next line
duplicate:
}
for(int k = 1; k <= 10; k++)
cout << array2[k] << " " << endl;
system("pause");
}
You could use a std::set to ensure uniqueness for you.
http://en.cppreference.com/w/cpp/container/set
You have three approaches:
compare each element one by one (O(N^2) performance)
sort your reference array and use a binary search to determine if the element exists (O(N*lnN) performance)
create a lookup hash (O(1) performance)
I can see two main sources of problems in your code: 1) the break statement, as it is, does not solve the problem of differentiating between the case when duplicate is found, and when the element in array1 should be added to array2. 2) There is no counter which would store the number of elements inserted so far into array2, this way they could not be copied to array2 next to each other. The code which fixes both is:
#include <iostream>
using namespace std;
int main()
{
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[10];
int array2_elements_inserted = 0;
for(int i = 0; i < 10; i++)
{
int temp = array1[i];
bool isDuplicate = false;
for(int j = 0; j < array2_elements_inserted; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
isDuplicate = true;
break;
}
}
if (!isDuplicate)
{
array2[array2_elements_inserted] = temp;
++array2_elements_inserted;
}
}
for(int k = 0; k < array2_elements_inserted; k++)
cout << array2[k] << " " << endl;
// system("pause");
}
Output:
10
2
5
4
6
9
8
First of all, use dynamic containers. Especially have a look at those provide by
the standard library, e.g. std::vector. Second, you should use a set data structure
to keep track of the elements you have seen before, e.g., std::set.
Then it's just an iteration on the input array and appending new elements to the
output array.
Here's an example:
#include <vector>
#include <set>
#include <iostream>
int main() {
// define and print input data
std::vector<int> v1 = {10,2,5,4,10,5,6,9,8,10};
for (int i : v1)
std::cout << i << " ";
std::cout << "\n";
// this will soon contain the output data
std::vector<int> v2;
// a set to keep track of the already seen elements
std::set<int> set;
// iterate the input array using range-based for loop
for (int i : v1) {
// check for duplicates
if (set.find(i) == set.end()) {
// first occurrence, insert to set, append to output data
set.insert(i);
v2.push_back(i);
}
else {
// seen before, do nothing
}
}
// print output data
for (int i : v2)
std::cout << i << " ";
std::cout << "\n";
}
The output:
$ g++ test.cc -std=c++11 && ./a.out
10 2 5 4 10 5 6 9 8 10
10 2 5 4 6 9 8
For reference:
http://en.cppreference.com/w/cpp/container/vector
http://en.cppreference.com/w/cpp/language/range-for
http://en.cppreference.com/w/cpp/container/set
http://en.cppreference.com/w/cpp/container/set/find

Pattern matching

I was just wondering if any other logic is possible for this problem:
Question : Find the number of pairs in a given string and output the sum of all the pairs and the unpaired elements. PS: The input is case sensitive.
Example O/P:
eeqe 3
aaaa
2
rwertr
5
I figured out the solution to this problem by first sorting the input string and then comparing adjacent elements as shown in the code below:
int main()
{
int t,count=0,pos=0;
char swap;
char a[201];
cin>>a;
int len=strlen(a);
//cout<<a<<endl;
for (int c = 0 ; c < ( len - 1 ); c++)
{
for (int d = 0 ; d < len - c - 1; d++)
{
if (a[d] > a[d+1]) /* For decreasing order use < */
{
swap = a[d];
a[d] = a[d+1];
a[d+1] = swap;
}
}
}
//cout<<a<<endl;
count=0;
for(int i=0;i<len;){
if(a[i]==a[i+1]){
count++;
i+=2;
//if(i== len-2)i++;
}
else{ count++; i++;}
}
//if(a[len-1]!=a[len-2])count++;
cout<<count<<endl;
return 0;
}
This code works fine. But, I was just wondering if there is any other efficient solution to this problem that doesn't involve sorting the entire input array.
It basically avoids sorting based on the idea that there are only 256 possible chars, so it's sufficent to count them.This is my solution:
int main()
{
std::string s; std::cin >> s;
int cnt[256] = {};
for (std::size_t i = 0; i < s.size(); ++i)
++cnt[static_cast<unsigned char>(s[i])];
int sum = 0;
for (std::size_t i = 0; i < 256; ++i)
sum += cnt[i]/2 + cnt[i]%2;
std::cout << sum << std::endl;
}
If, for example, the string contains 5 times an 'a', this allows 5/2 pairs (integer division) and 1 remains unpaired (because 5 is odd => 5%2 is 1)
Edit: Because we are here in SO:
int main()
{
std::array<int, 256> cnt{-1}; // last char will be '\0', ignore this.
std::for_each(std::istreambuf_iterator<char>(std::cin.rdbuf()),
std::istreambuf_iterator<char>{},
[&](unsigned char c){++cnt[c];});
std::cout << std::accumulate(cnt.begin(), cnt.end(), 0,
[](int i, int c)->int{return i+(c/2)+(c%2);}) << '\n';
}