program that converts spelled out numbers in to its digit form. (c++) - c++14

I am trying to make a program that converts numbers in digit form to spelled out numbers, and also from spelled-out numbers in to digit numbers (numbers from 0-10). So far my program can do the digit to spelled-out convertion, but I am not sure how to do it the other way around. I am grateful for any help. This is my code so far:
#include "std_lib_facilities.h"
using namespace std;
int main()
{
vector <string> string_val = {"zeroe","one","two","three","four","five","six","seven" ,"eight","nine"};
int integer =0;
string spelled_integer;
cout<<"Enter a number bethween '0' and '10'\n";
while(cin>>integer)
{
if(integer<10)
cout<<"your number in spelled out form is: "<<string_val[integer] <<'\n';
else
cout<<"your number is either to low, or to big, try again.\n";
}
}

As #pm100 suggested in a comment, an std::map is the perfect solution for you. Here is a sample:
int main()
{
std::map<std::string, int> numbers {
{"zero", 0},
{"one", 1},
{"two", 2}
};
std::cout << numbers["two"];
}
The above sample prints 2. For the other way around (the one you've already done) I would also suggest using a map. They are very powerful containers worth exploring.

Related

Sorting multiple arrays using CUDA/Thrust

I have a large array that I need to sort on the GPU. The array itself is a concatenation of multiple smaller subarrays that satisfy the condition that given i < j, the elements of the subarray i are smaller than the elements of the subarray j. An example of such array would be {5 3 4 2 1 6 9 8 7 10 11},
where the elements of the first subarray of 5 elements are smaller than the elements of the second subarray of 6 elements. The array I need is {1, 2, 3, 4, 5, 6, 7, 10, 11}. I know the position where each subarray starts in the large array.
I know I can simply use thrust::sort on the whole array, but I was wondering if it's possible to launch multiple concurrent sorts, one for each subarray. I'm hoping to get a performance improvement by doing that. My assumption is that it would be faster to sort multiple smaller arrays than one large array with all the elements.
I'd appreciate if someone could give me a way to do that or correct my assumption in case it's wrong.
A way to do multiple concurrent sorts (a "vectorized" sort) in thrust is via the marking of the sub arrays, and providing a custom functor that is an ordinary thrust sort functor that also orders the sub arrays by their key.
Another possible method is to use back-to-back thrust::stable_sort_by_key as described here.
As you have pointed out, another method in your case is just to do an ordinary sort, since that is ultimately your objective.
However I think its unlikely that any of the thrust sort methods will give a signficant speed-up over a pure sort, although you can try it. Thrust has a fast-path radix sort which it will use in certain situations, which the pure sort method could probably use in your case. (In other cases, e.g. when you provide a custom functor, thrust will often use a slower merge-sort method.)
If the sizes of the sub arrays are within certain ranges, I think you're likely to get much better results (performance-wise) with block radix sort in cub, one block per sub-array.
Here is an example that uses specific sizes (since you've given no indication of size ranges and other details), comparing a thrust "pure sort" to a thrust segmented sort with functor, to the cub block sort method. For this particular case, the cub sort is fastest:
$ cat t1.cu
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/sort.h>
#include <thrust/scan.h>
#include <thrust/equal.h>
#include <cstdlib>
#include <iostream>
#include <time.h>
#include <sys/time.h>
#define USECPSEC 1000000ULL
const int num_blocks = 2048;
const int items_per = 4;
const int nTPB = 512;
const int block_size = items_per*nTPB; // must be a whole-number multiple of nTPB;
typedef float mt;
unsigned long long dtime_usec(unsigned long long start){
timeval tv;
gettimeofday(&tv, 0);
return ((tv.tv_sec*USECPSEC)+tv.tv_usec)-start;
}
struct my_sort_functor
{
template <typename T, typename T2>
__host__ __device__
bool operator()(T t1, T2 t2){
if (thrust::get<1>(t1) < thrust::get<1>(t2)) return true;
if (thrust::get<1>(t1) > thrust::get<1>(t2)) return false;
if (thrust::get<0>(t1) > thrust::get<0>(t2)) return false;
return true;}
};
// from: https://nvlabs.github.io/cub/example_block_radix_sort_8cu-example.html#_a0
#define CUB_STDERR
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cub/block/block_load.cuh>
#include <cub/block/block_store.cuh>
#include <cub/block/block_radix_sort.cuh>
using namespace cub;
//---------------------------------------------------------------------
// Globals, constants and typedefs
//---------------------------------------------------------------------
bool g_verbose = false;
bool g_uniform_keys;
//---------------------------------------------------------------------
// Kernels
//---------------------------------------------------------------------
template <
typename Key,
int BLOCK_THREADS,
int ITEMS_PER_THREAD>
__launch_bounds__ (BLOCK_THREADS)
__global__ void BlockSortKernel(
Key *d_in, // Tile of input
Key *d_out) // Tile of output
{
enum { TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD };
// Specialize BlockLoad type for our thread block (uses warp-striped loads for coalescing, then transposes in shared memory to a blocked arrangement)
typedef BlockLoad<Key, BLOCK_THREADS, ITEMS_PER_THREAD, BLOCK_LOAD_WARP_TRANSPOSE> BlockLoadT;
// Specialize BlockRadixSort type for our thread block
typedef BlockRadixSort<Key, BLOCK_THREADS, ITEMS_PER_THREAD> BlockRadixSortT;
// Shared memory
__shared__ union TempStorage
{
typename BlockLoadT::TempStorage load;
typename BlockRadixSortT::TempStorage sort;
} temp_storage;
// Per-thread tile items
Key items[ITEMS_PER_THREAD];
// Our current block's offset
int block_offset = blockIdx.x * TILE_SIZE;
// Load items into a blocked arrangement
BlockLoadT(temp_storage.load).Load(d_in + block_offset, items);
// Barrier for smem reuse
__syncthreads();
// Sort keys
BlockRadixSortT(temp_storage.sort).SortBlockedToStriped(items);
// Store output in striped fashion
StoreDirectStriped<BLOCK_THREADS>(threadIdx.x, d_out + block_offset, items);
}
int main(){
const int ds = num_blocks*block_size;
thrust::host_vector<mt> data(ds);
thrust::host_vector<int> keys(ds);
for (int i = block_size; i < ds; i+=block_size) keys[i] = 1; // mark beginning of blocks
thrust::device_vector<int> d_keys = keys;
for (int i = 0; i < ds; i++) data[i] = (rand()%block_size) + (i/block_size)*block_size; // populate data
thrust::device_vector<mt> d_data = data;
thrust::inclusive_scan(d_keys.begin(), d_keys.end(), d_keys.begin()); // fill out keys array 000111222...
thrust::device_vector<mt> d1 = d_data; // make a copy of unsorted data
cudaDeviceSynchronize();
unsigned long long os = dtime_usec(0);
thrust::sort(d1.begin(), d1.end()); // ordinary sort
cudaDeviceSynchronize();
os = dtime_usec(os);
thrust::device_vector<mt> d2 = d_data; // make a copy of unsorted data
cudaDeviceSynchronize();
unsigned long long ss = dtime_usec(0);
thrust::sort(thrust::make_zip_iterator(thrust::make_tuple(d2.begin(), d_keys.begin())), thrust::make_zip_iterator(thrust::make_tuple(d2.end(), d_keys.end())), my_sort_functor());
cudaDeviceSynchronize();
ss = dtime_usec(ss);
if (!thrust::equal(d1.begin(), d1.end(), d2.begin())) {std::cout << "oops1" << std::endl; return 0;}
std::cout << "ordinary thrust sort: " << os/(float)USECPSEC << "s " << "segmented sort: " << ss/(float)USECPSEC << "s" << std::endl;
thrust::device_vector<mt> d3(ds);
cudaDeviceSynchronize();
unsigned long long cs = dtime_usec(0);
BlockSortKernel<mt, nTPB, items_per><<<num_blocks, nTPB>>>(thrust::raw_pointer_cast(d_data.data()), thrust::raw_pointer_cast(d3.data()));
cudaDeviceSynchronize();
cs = dtime_usec(cs);
if (!thrust::equal(d1.begin(), d1.end(), d3.begin())) {std::cout << "oops2" << std::endl; return 0;}
std::cout << "cub sort: " << cs/(float)USECPSEC << "s" << std::endl;
}
$ nvcc -o t1 t1.cu
$ ./t1
ordinary thrust sort: 0.001652s segmented sort: 0.00263s
cub sort: 0.000265s
$
(CUDA 10.2.89, Tesla V100, Ubuntu 18.04)
I have no doubt that your sizes and array dimensions don't correspond to mine. The purpose here is to illustrate some possible methods, not a black-box solution that works for your particular case. You probably should do benchmark comparisons of your own. I also acknowledge that the block radix sort method for cub expects equal-sized sub-arrays, which you may not have. It may not be a suitable method for you, or you may wish to explore some kind of padding arrangement. There's no need to ask this question of me; I won't be able to answer it based on the information in your question.
I don't claim correctness for this code or any other code that I post. Anyone using any code I post does so at their own risk. I merely claim that I have attempted to address the questions in the original posting, and provide some explanation thereof. I am not claiming my code is defect-free, or that it is suitable for any particular purpose. Use it (or not) at your own risk.

How to scan integers in double loops. c-language

I would like to know how to scan integers into two arrays.
My codes is as follow, but it doesn't work.I use C language by the way.
#include<stdio.h>
int main()
{
int a[10]={0};
int b[10];
for(int i=1;i<=3;i++)
{
printf("input b");
scanf("%d",b[i]);
for(int j=1;j<=3;j++)
{
printf("input a");
scanf("%d",a[j]);
}
}
}
scanf requires an address to know where to store the value it reads. You can get the address of a local variable using '&'.
scanf("%d", &b[i]);
scanf("%d", &a[j]);
You should read up on pointers to understand how they work in C. It's a fair amount to take in but you will become a much better C programmer once you understand it.
These are two guides I found, Pointers in C and The 5-minutes Guide to C Pointers.

Iterate over first N elements of c++11 std::array

I am using a std::array (c++11). I am choosing to use a std::array because I want the size to be fixed at compile time (as opposed to runtime). Is there anyway I can iterate over the first N elements ONLY. i.e. something like:
std::array<int,6> myArray = {0,0,0,0,0,0};
std::find_if(myArray.begin(), myArray.begin() + 4, [](int x){return (x%2==1);});
This is not the best example because find_if returns an iterator marking the FIRST odd number, but you get the idea (I only want to consider the first N, in this case N=4, elements of my std::array).
Note: There are questions similar to this one, but the answer always involves using a different container (vector or valarray, which is not what I want. As I described early, I want to size of the container to be fixed at compile time).
Thank you in advance!!
From the way you presented your question, I assume that you say "iterate over", but actually mean "operate on with an algorithm".
The behaviour is not specific to a container, but to the iterator type of the container.
std::array::iterator_type satisfies RandomAccessIterator, the same as std::vector and std::deque.
That means that, given
std::array<int,6> myArray = {0,0,0,0,0,0};
and
auto end = myArray.begin() // ...
you can add a number n to it...
auto end = myArray.begin() + 4;
...resulting in an iterator to one element beyond the nth element in the array. As that is the very definition for an end iterator for the sequence,
std::find_if(myArray.begin(), myArray.begin() + 4, ... )
works just fine. A somewhat more intuitive example:
#include <algorithm>
#include <array>
#include <iostream>
#define N 4
int main()
{
std::array<char, 6> myArray = { 'a', 'b', 'c', 'd', 'e', 'f' };
auto end = myArray.begin() + N;
if ( std::find( myArray.begin(), end, 'd' ) != end )
{
std::cout << "Found.\n";
}
return 0;
}
This finds the 4th element in the array, and prints "Found."
Change #define N 4 to #define N 3, and it prints nothing.
Of course, this is assuming that your array has N elements. If you aren't sure, check N <= myArray.size() first and use myArray.end() instead if required.
For completeness:
A BidirectionalIterator (list, set, multiset, map, multimap) only supports ++ and --.
A ForwardIterator (forward_list, unordered_set, unordered_multiset, unordered_map, unordered_multimap) only supports ++.
An InputIterator does not support dereferencing the result of postfix ++.
If you want to iterate over the first N numbers of a std::array, just do something like:
#include <iostream>
#include <array>
int main() {
constexpr const int N = 4;
std::array<int, 6> arr{ 0, 1, 2, 3, 4, 5 };
for (auto it = std::begin(arr); it != std::begin(arr) + N && it != std::end(arr); ++it)
std::cout << *it << std::endl;
}
With C++20, a std::span can be used to create a subset view of a std::array much like std::string_view does for std::string. The span replaces maintaining the variable 'N' for the number of sub-elements.
auto part = std::span(myArray).first(4);
std::find_if(part.begin(), part.end(), [](int x) {return (x % 2 == 1); });
A std::span offers many other benefits. It can be used in range based for loops. And by using std::span.subspan, a span can view any range of elements, not limited to just the first N. A span can also be used not just with std::array, but also with C arrays, std::vector, and other contiguous containers.

i dont know what what is the error its printing 3.18e+04

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double A,R;
R=100.64;
R=R*R;
A=3.14159*R;
cout<< setprecision(3)<<A<<endl;
return 0;
}
The reasonably precise and accurate(a) value you would get from those calculations (mathematically) is 31,819.31032.
You have asked for a precision of three digits and, with that value and the floating point format currently active (probably std::defaultfloat), it's only giving you three significant digits:
3.18e+04 (3.18x104 in mathematical form).
If your intent is to instead show three digits after the decimal point, you can do that with the std::fixed manipulator:
#include <iostream>
#include <iomanip>
int main() {
double R = 100.64;
double A = 3.14159 * R * R;
std::cout << std::setprecision(3) << std::fixed << A << '\n';
return 0;
}
This gives 31819.310.
(a) Make sure you never conflate these two, they're different concepts. See for example, the following values of π you may come up with:
Value
Properties
9
Both im-precise and in-accurate.
3
Im-precise but accurate.
2.718281828459
Precise but in-accurate.
3.141592653590
Both precise and accurate.
π
Has maximum precision and accuracy.

Finding three numbers occurring even number of times in an array

In an array except three numbers all numbers occur odd number of times. How to find all three numbers occurring even number of times in an array?
I can get till a point where I have xor of all three even occurring numbers. How to get the three numbers from that xor value? My approach till now:
#include <iostream>
#include <set>
using namespace std;
int main() {
// Find the 3 numbers occuring even times in an array
int arr[] = {1,6,2,88,34,4,98,25,61,7,2,78,2,78,8,25,9,34,56,331};
int a = arr[0];
for (int i=1;i<20;i++)
a ^= arr[i];
set<int> myset;
myset.insert(arr,arr+20);
set<int>::iterator it;
for (it=myset.begin(); it!=myset.end(); ++it)
a ^= *it;
cout<<a<<endl; // a stores xor of the three numbers occuring even number of times, i.e., (25^78^34)=117
return 0;
}
Note: Hashtable and sorting should not be used. The solution should be in O(n) time.
The solution of your problem is as
`
#include <iostream>
#include <set>
using namespace std;
int main() {
// Find the 3 numbers occuring even times in an array
int arr[] = {1,6,2,88,34,4,98,25,61,7,2,78,2,78,8,25,9,34,56,331};
set<int> myset;
set<int> myset_final;
for (int i=1;i<20;i++)
{
if(myset.exists(a[i]))
myset.remove(a[i]);
else myset.insert(a[i]);
}
for(int i=0;i<i<20;i++)
{
if(!myset.exists(a[i]))
myset_final.insert(a[i]);
}
//Now the myset_final contains the numbers that are occured even number of times.
return 0;
}
`
This is the best solution according to me but not the O(n) it O(nlog(n)).
I found this solution which does the job in O(n) time and O(1) space but the only thing is the numbers of the array can be in range [0,63].

Resources