I want to write a loop, that can give me the dimensions of an array. I want to make it usable for any array and it should return the sizes of the dimensions.
int arr[3][5][10][9] ;
cout << "dimension 1: " << sizeof(arr)/sizeof(arr[0]) << endl;
cout << "dimension 2: " << sizeof(arr[0])/sizeof(arr[0][0]) << endl;
cout << "dimension 3: " << sizeof(arr[0][0])/sizeof(arr[0][0][0]) << endl;
cout << "dimension 4: " << sizeof(arr[0][0][0])/sizeof(arr[0][0][0][0]) << endl;
cout << "dimension 5: " << sizeof(arr[0][0][0][0])/sizeof(arr[0][0][0][0][0]) << endl;
This should return 3,5,10,9 (and fail for the last statement).
So the pattern seems clear "each iteration add [0] after arr. The last iteration will fail, which should stop the while-loop.
How can I "concatenate + evaluate" the array name?
I would also appreciate help on what test checks "Will this fail?", or "Is there another dimension?" in C++, as I'm just learning it.
if you are using c++ 17 compiler, you can use type traits structs std::rank and std::extent as following
#include <iostream>
#include <type_traits>
template<typename T>
void print_dimension(std::size_t i) {
if (std::rank_v<T> > 0) {
std::cout << "Dimension " << i << ":" << std::extent_v<T> << std::endl;
print_dimension<typename std::remove_extent_t<T>>(i + 1);
}
}
int main() {
int arr[3][5][10][9] ;
print_dimension<decltype(arr)>(1);
return 0;
}
If you are using C++ 11/14 compiler, it would need slight modification
#include <iostream>
#include <type_traits>
template<typename T>
void print_dimension(std::size_t i) {
if (std::rank<T>::value > 0) {
std::cout << "Dimension " << i << ":" << std::extent<T>::value << std::endl;
print_dimension<typename std::remove_extent<T>::type>(i + 1);
}
}
int main() {
int arr[3][5][10][9] ;
print_dimension<decltype(arr)>(1);
return 0;
}
Related
I have this function to solve the Tower of Hanoi problem and fortunately It's working good but can anybody explain to me if the function is calling it self before the cout statement in case m!=0 then how does it ever reach the cout statement or even the other call of itself ??
#include <iostream>
using namespace std;
void Hanoi(int m, char a, char b, char c){
if(m == 1){
cout << "Move disc " << m << " from " << a << " to " << c << endl;
}else{
Hanoi(m-1, a,c,b);
cout << "Move disc " << m << " from " << a << " to " << c << endl;
Hanoi(m-1,b,a,c);
}
}
int main(){
int discs;
cout << "Enter the number of discs: " << endl;
cin >> discs;
Hanoi(discs, 'A', 'B', 'C');
return 0;
}
Calling Hanoi(m), where m > 1: First it executes Hanoi(m-1) and all resulting calls. Then it executes cout. Then it executes Hanoi(m-1) and all resulting calls a second time.
Consider m == 3:
Hanoi(3)
Hanoi(2)
Hanoi(1)
cout
cout
Hanoi(1)
cout
cout
Hanoi(2)
Hanoi(1)
cout
cout
Hanoi(1)
cout
I have just studied c++ templates and it was great that the books example compiled and worked. Then in the exercises at the end of the chapter I tried my own template programme. The code simple passes an array to the template function and it determines the largest value in the array. The problem is that when the type double array is passed the template is treating it as type int and displaying 5 as the larges value and not 5.0.
Here is my code
// Exercise 5.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
template <typename T>
T max5(const T array[]);
int main()
{
using std::cout;
using std::cin;
using std::endl;
int intA[5]{ 1, 2, 5, 4, 3 };
double doubleA[5]{ 1.0, 2.0, 5.0, 4.0, 3.0 };
cout << "Max int " << max5(intA) << endl;
cout << "Max double " << max5(doubleA) << endl;
cin.get();
cin.get();
return 0;
}
template <typename T>
T max5(const T array[])
{
T max = array[0];
for (int i = 1; i < 5; i++)
{
if (array[i] > max) max = array[i];
//std::cout << "Max: " << max << std::endl;
}
return max;
}
Any ideas as to why?
Regards
Mickydint
You're getting the correct types back, the problem is with you displaying them.
cout << "int == " << typeid(max5(intA)).name() << endl;
cout << "double == " << typeid(max5(doubleA)).name() << endl;
std::cout has different ways of showing higher precision or different formatting.
Like:
std::setprecision
std::fixed
std::scientific
std::hexfloat
std::defaultfloat
and std::showpoint as Zulukas already pointed out.
// Exercise 5.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <typeinfo>
template <typename T>
T max5(const T array[]);
int main()
{
using std::cout;
using std::cin;
using std::endl;
int intA[5]{ 1, 2, 5, 4, 3 };
double doubleA[5]{ 1.0, 2.0, 5.0, 4.0, 3.0 };
cout << "int == " << typeid(max5(intA)).name() << endl;
cout << "double == " << typeid(max5(doubleA)).name() << endl;
cout << std::showpoint;
cout << "Max int " << max5(intA) << endl;
cout << "Max double " << max5(doubleA) << endl;
cout << std::noshowpoint;
cout << std::fixed;
cout << "Max int " << max5(intA) << endl;
cout << "Max double " << max5(doubleA) << endl;
cin.get();
cin.get();
return 0;
}
template <typename T>
T max5(const T array[])
{
T max = array[0];
for (int i = 1; i < 5; i++)
{
if (array[i] > max) max = array[i];
//std::cout << "Max: " << max << std::endl;
}
return max;
}
Live
In CPP file #1, I'm trying to loop through the array to see if any of the inputed names match Mordor or the_Vale (from CPP file #2 towards the bottom), however my loop is not working and I only know how to loop through a string array, not a char
#Header File#
#ifndef KINGDOM_H
#define KINGDOM_H
namespace westeros
{
class Kingdom
{
public: //Makes this class public to the rest of the code
char m_name[32];
int m_population;
int count = 0;
};
void display(Kingdom&);
void display(Kingdom* k, int x);
void display(Kingdom* k, int x, int z);
void display(Kingdom* k, int x, char foo[]);
}
#endif
#CPP FIle #1#
#include <iostream>
#include "kingdom.h"
void display(Kingdom* k, int x, char foo[])
{
int a = 0;
int found = 0;
cout << "Searching for kingdom " << foo << " in Westeros" << endl;
for (a; a < x; a++)
{
if (k[a].m_name == foo)
//(strcmp(k[a].m_name) == 0)//Not working
{
cout << k[a].m_name << ", population " << k[a].m_population << endl;
found = 1;
}
}
if (found == 0)
{
cout << foo << " is not part of Westeros." << endl;
}
}
}
## CPP File (main) #2##
#include <iostream>
#include "kingdom.h"
using namespace std;
using namespace westeros;
int main(void)
{
int count = 0; // the number of kingdoms in the array
// TODO: declare the kingdoms pointer here (don't forget to initialize it)
Kingdom* pKingdoms = nullptr;
cout << "==========" << endl
<< "Input data" << endl
<< "==========" << endl
<< "Enter the number of kingdoms: ";
cin >> count;
cin.ignore();
pKingdoms = new Kingdom[count];
for (int i = 0; i < count; ++i)
{
// TODO: add code to accept user input for the kingdoms array
int x = 0;
x++;
cout << "Enter the name for kingdom #" << x + i << ": ";
cin >> pKingdoms[i].m_name;
cout << "Enter the number people living in " << pKingdoms[i].m_name << ": ";
cin >> pKingdoms[i].m_population;
}
cout << "==========" << endl << endl;
// testing that "display(...)" works
cout << "------------------------------" << endl
<< "The first kingdom of Westeros" << endl
<< "------------------------------" << endl;
display(pKingdoms[0]);
cout << "------------------------------" << endl << endl;
// This is where I am having the problem
display(pKingdoms, count, "Mordor");
cout << endl;
display(pKingdoms, count, "The_Vale");
cout << endl;
cout << endl;
delete[] pKingdoms;
pKingdoms = nullptr;
return 0;
}
if (k[a].m_name == foo)
This is not how you compare two C-Style strings. This only compares the pointers, which should result in false almost certainly. You could use strcmp (#include <string.h>):
if (!strcmp(k[a].m_name, foo))
A better way, though, since you're programming in C++, use std::string:
std::string m_name;
and the comparison would have worked flawlessly.
I'm new to C++ and I am having some trouble with an assignment. Here is my program so far:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
void fight(string heroName, int arrowCount, int enemyCount);
int main(int argc, char** argv) {
string heroName = "Legolas";
int arrowCount = 3;
int enemyCount = 3;
cout << "Welcome to the Arena, the battle will begin shortly." << endl;
system("pause");
cout << "\nToday's competitors: " << "\n" << heroName << "\n" << "3 Orcs" << endl;
system("pause");
cout << "\n" << heroName << " will be given 3 arrows" << "\n" << "3 Orcs will be given daggers. \n";
system("pause");
cout << "\nThe battle begins in...\n 3...\n 2...\n 1..." << endl;
system("pause");
fight(heroName, arrowCount, enemyCount);
}
void fight(string heroName, int arrowCount, int enemyCount) {
for (int x = arrowCount; x <= 0; x--) {
if (arrowCount == 3) {
cout << "\n" << heroName << " fires arrow at Azog." << "\nAzog has fallen due to lobotomy by arrow." << "\nLegolas notices he has 2 arrows remaining." << endl;
system("pause");
}
if (arrowCount == 2) {
cout << "\n" << heroName << " fires arrow at Dular." << "\nDular has taken an arrow to the knee and is now longer an adventurer." << "\nLegolas notices he has 1 arrow remaining." << endl;
system("pause");
}
if (arrowCount == 1) {
cout << "\n" << heroName << " fires arrow at Nagrub." << "\nNagrub has lost his testicles." << "\nLegolas notices he is out of Arrows." << endl;
system("pause");
}
}
}
The issue that I'm having is it seems that the for loop isn't initializing. Everything runs fine up to the "void fight" part of the program. How can I correct this?
Did you mean for (int x = arrowCount; x >= 0; x--) {? Note that the for loop conditional check is evaluated before the loop body is ran.
Currently your loop will terminate if x is positive, which judging from your variable name, is most likely to be the case.
Also note that the body of the for loop depends on neither x, nor enemyCount, which seems odd.
The code that I posted below is supposed to work in recursion (the Sort() function) even up to 1kk times. The problem is: when the Sort() function gets into loop number 43385 the console stops working and alerts: "The program has stopped working". Is it a problem with memory? If yes, where is the bad part of the code? Greetings.
#include <iostream>
#include <string>
using namespace std;
string a, b;
int n=0,i=0,counter=0;
int Sort(int i)
{
int x=0,y=0,tmp0=0;
char tmp1;
for(x=i;x<n;x++) {
if(a[x]==b[i]){
tmp0=x;
tmp1=a[x];
break;
}
else
continue;
}
for(y=tmp0;y>=i;y--)
y==i ? a[i]=tmp1 : a[y]=a[y-1];
counter+=tmp0-i;
if(i==n-1)
return counter;
else
Sort(i+1);
}
int main()
{
cin >> n >> a >> b;
Sort(0);
return 0;
}
Perhaps a call stack overflow because of too deep recursion?
To add to iltal's comment, you may want to print out information on strings a, b: a.size(), a.length(), a.capacity(), a.max_size()
I'm not sure what this code is trying to do. Here's a revision, with some print statements added, along with a random string generator.
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
string a, b;
int n=0,i=0,counter=0;
int Sort(int i)
{
int x=0,y=0,tmp0=0;
char tmp1;
for(x=i;x<n;x++) {
if(a[x]==b[i]){
tmp0=x;
tmp1=a[x];
cout << "x = " << x << " set tmp0 to " << tmp0 << " and tmp1 to " << tmp1 << endl;
break;
}
else
continue;
}
for(y=tmp0;y>=i;y--)
y==i ? a[i]=tmp1 : a[y]=a[y-1];
counter+=tmp0-i;
cout << " endof sort: a is " << a << endl;
cout << " b is " << b << endl;
if(i==n-1) {
cout << "Returning counter " << counter << endl;
return counter;
} else {
cout << "Running sort(" << i << " + 1)" << endl;
Sort(i+1);
}
}
string randomStrGen(int length) {
static string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
string result;
result.resize(length);
for (int i = 0; i < length; i++)
result[i] = charset[rand() % charset.length()];
return result;
}
int main()
{
n = 50;
srand(time(NULL));
string a0, b0;
a0 = randomStrGen(n);
a = a0;
b0 = randomStrGen(n);
b = b0;
// cin >> n >> a >> b;
cout << "Max string size is " << a.max_size() << endl;
cout << "Calling sort" << endl
<< " n is " << n << endl
<< " a is " << a << endl
<< " b is " << b << endl;
Sort(0);
cout << " endof program: a inital: " << a0 << endl;
cout << " a final: " << a << endl;
cout << " b inital: " << b0 << endl;
cout << " b final: " << b << endl;
return 0;
}
counter is of type int but it has a lot of values summed in it which may be in all larger than int. maybe try int64?
You could hard code some test cases, like n = 20, a = "xyz...", b = "abc...", and add print statements to your sort function to track what is going on. Also, it may be helpful to add some comments to clarify what the purpose of the different loops are.