Create and array with random numbers and strings

How do I create an array with random numbers and strings?

sample output is:
100001, wtfxltnqbkviye, zhajstwyxcaptn, 9572, 52173, 123, 25908 0 92106
77831 41707 109114 26283 5399 149521 139501 108583 57303


For each line you must randomly generate:
 A uniqueID of 6 digits.
 A fname and a lname, (not unique) of random length between 8 and 16 characters, made up of random chars. This can be stored in separate variables or within its own struct
 A ID (not unique) of 4 digits.
 A pay between 20,000 and 100,000(inclusive).
 Days Worked, 0-21 (inclusive) days for each month, for 12 months out of the year. The sum of days worked for all months will be stored in the file.
 Sales total for each day worked in a month are added to the monthly Sales Total. Monthly totals are separated by spaces
o This can be stored in a single string
o Sales should be higher for employees with higher salaries:
 Salaries<60000 , daily sales should be from 1000-15000 a day(for each day worked)
 Salaries>60000, daily sales should be from 3000-20000 a day(for each day worked)
Last edited on
This is the outline for the code that I am fighting with:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int genID(employee IDArray, employee empID)

{
    int ID[5000];

    //do this for 5000 employees with unique IDs
    for (int i, i<ID, i++)
    {
        ID = rand() %7;
    }
    
    
    return ID;
}


Here are my structs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct employee
{
    int empID;
    
    employee Name;
    
    int storeID;
    int salary;
    int daysWorked, sumDaysWorked;
    int totalSalesofDay;
    
    employee IDArray[];
};

employee name
{
   string firstName, lastName; 
};
Last edited on
Not enough information.

each element is defined by this set

What do you mean by element?

For each line you must randomly generate

What are the "lines" here?

In your struct you mention "storeID", but there is no mention of "stores" in your post.

What is the overall purpose of your program?
It seems like you are randomly generating test data.
depending on what you want, you can craft a string:

string random_hex{"0123456789abcdef"};
and take a <random> into {0, string length}
to pick off each letter:
for(a random size)
randomstr += random_hex[random_index];

kind of like that (its pseudocode of the idea. people keep trying to compile my pseudocode).
I am randomly generating test data, 5000 lines worth.

I guess that the first step is that I need to randomly generate a 6-digit number for so many iterations and verify that they are all unique. Then assign the 6-digit number to an int or string variable.

That will be the first function in the program.

The overall purpose of the program is to generate random data, sort the data by the 6-digit number, calculate totals for 'monthly sales' and print it all to a txt file.

storeID is 4-digit random, non-unique number identifying the 'store' each person works at.
Line 5,12: You struct contains itself. This is an error.

Line 12: What is IDArray?

Lines 15-18: This struct is unnecessary.
Possibly something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <random>
#include <iostream>
#include <fstream>
#include <string>
#include <set>
#include <vector>

struct Name
{
	std::string firstName;
	std::string lastName;
};

struct Employee
{
	unsigned empID {};
	Name names;
	unsigned storeID {};
	unsigned salary {};
	unsigned daysWorked {};
	unsigned MonthlySales[12] {};
};

std::ostream& operator<<(std::ostream& os, const Employee& e) {
	os << e.empID << ", " << e.names.firstName << ", " << e.names.lastName << ", "
		<< e.storeID << ", " << e.salary << ", " << e.daysWorked << ", ";

	for (unsigned m = 0; m < 12; ++m)
		os << e.MonthlySales[m] << ' ';

	return os;
}

std::mt19937 rng(std::random_device {}());

std::string rndName() {
	constexpr unsigned minlen {8};
	constexpr unsigned maxlen {16};

	static const std::uniform_int_distribution<unsigned> strdist(minlen, maxlen);
	static const std::uniform_int_distribution<unsigned> chdist('a', 'z');
	std::string str(strdist(rng), 0);

	for (auto& ch : str)
		ch = static_cast<char>(chdist(rng));

	return str;
}

unsigned rndNum(unsigned first, unsigned last) {
	const std::uniform_int_distribution<unsigned> numdist(first, last);

	return numdist(rng);
}

int main()
{
	constexpr size_t noRows {5};
	constexpr size_t noMonths {12};

	std::set<unsigned> uids;
	std::vector<Employee> employees;

	for (size_t r = 0; r < noRows; ++r) {
		Employee emp;

		do {
			emp.empID = rndNum(100'000, 999'999);
		} while (!uids.insert(emp.empID).second);

		emp.names.firstName = rndName();
		emp.names.lastName = rndName();
		emp.storeID = rndNum(1'000, 9999);
		emp.salary = rndNum(20'000, 100'000);
		emp.daysWorked = rndNum(0, 21 * noMonths);

		for (unsigned m = 0; m < noMonths; ++m)
			emp.MonthlySales[m] = emp.daysWorked * (emp.salary < 60'000 ? rndNum(1'000, 15'000) : rndNum(3'000, 20'000));

		employees.emplace_back(emp);
	}

	for (const auto& e : employees)
		std::cout << e << '\n';
}



555641, sqnnhdcfer, ubrkyajdppx, 4643, 66843, 17, 62186 293454 133399 198934 213792 65467 313463 68935 252331 167773 63342 303994
467866, exhizvdff, gglklkjtmjlz, 4164, 59388, 31, 449376 400985 214489 252154 168547 374883 380649 337342 79639 113708 263717 70091
131915, ewgnwkpuixzrfl, vrzridtzuaefvhha, 6030, 82966, 156, 1206972 1255488 1850316 2834520 1919112 1064856 2323308 929604 2181816 1812876 709020 1819584
234167, xgoaybraztzjd, ygxnvhhcbt, 8376, 76318, 165, 851565 2827935 2921820 2854830 827805 2669535 1388640 2662275 2635050 1282215 3106290 1604790
390871, jfvrihfpvk, ledlofwimkhdpi, 1098, 59706, 233, 277969 1560867 325501 1374467 2330466 2144532 1451124 2395240 235097 1770800 1648475 405886

Last edited on
^^
Thank you! I got it sorta functioning. I'm using a bubble sort to sort the data by the beginning of the line, so it's taking forever .

How would I collect some of the data? like, sort out the 5 highest "sales" and lowest "sales".
sorting it and taking the top and bottom N items.
if bubblesort takes to long, use something else. It is the slowest sort you can create that is not intentionally doing extra work. Use the c++ sort or if you insist on writing your own, try shell or the improved bubble (read this and the next one on comb sort) http://techieme.in/improving-bubble-sort/ the slight improvements to pure bubble are polishing a poo but comb is pretty solid.
Last edited on
Just use a std::map to hold the data. This will automatically keep it in sorted order.

Something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <random>
#include <iostream>
#include <fstream>
#include <string>
#include <set>
#include <map>

struct Name
{
	std::string firstName;
	std::string lastName;
};

struct Employee
{
	unsigned empID {};
	Name names;
	unsigned storeID {};
	unsigned salary {};
	unsigned daysWorked {};
	unsigned MonthlySales[12] {};
};

std::ostream& operator<<(std::ostream& os, const Employee& e) {
	os << e.empID << ", " << e.names.firstName << ", " << e.names.lastName << ", "
		<< e.storeID << ", " << e.salary << ", " << e.daysWorked << ", ";

	for (unsigned m = 0; m < 12; ++m)
		os << e.MonthlySales[m] << ' ';

	return os;
}

std::mt19937 rng(std::random_device {}());

std::string rndName() {
	constexpr unsigned minlen {8};
	constexpr unsigned maxlen {16};

	static const std::uniform_int_distribution<unsigned> strdist(minlen, maxlen);
	static const std::uniform_int_distribution<unsigned> chdist('a', 'z');
	std::string str(strdist(rng), 0);

	for (auto& ch : str)
		ch = static_cast<char>(chdist(rng));

	return str;
}

unsigned rndNum(unsigned first, unsigned last) {
	const std::uniform_int_distribution<unsigned> numdist(first, last);

	return numdist(rng);
}

int main()
{
	constexpr size_t noRows {5};
	constexpr size_t noMonths {12};

	std::set<unsigned> uids;
	std::map<unsigned, Employee> employees;

	for (size_t r = 0; r < noRows; ++r) {
		Employee emp;

		do {
			emp.empID = rndNum(100'000, 999'999);
		} while (!uids.insert(emp.empID).second);

		emp.names.firstName = rndName();
		emp.names.lastName = rndName();
		emp.storeID = rndNum(1'000, 9999);
		emp.salary = rndNum(20'000, 100'000);
		emp.daysWorked = rndNum(0, 21 * noMonths);

		for (unsigned m = 0; m < noMonths; ++m)
			emp.MonthlySales[m] = emp.daysWorked * (emp.salary < 60'000 ? rndNum(1'000, 15'000) : rndNum(3'000, 20'000));

		employees.emplace(emp.empID, emp);
	}

	for (const auto& [id, emp] : employees)
		std::cout << emp << '\n';
}


For 5 highest/lowest sales, these are easiest done when they are generated. You could maintain say a max 5 element deque for each.


> How would I collect some of the data? like, sort out the 5 highest "sales" and lowest "sales".

Use a selection algorithm; for example introselect https://en.wikipedia.org/wiki/Introselect

The standard library has std::nth_element (linear complexity on average).
https://en.cppreference.com/w/cpp/algorithm/nth_element
One way to produce the random data and the top 5 high and bottom 5 total sales is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <random>
#include <iostream>
#include <fstream>
#include <string>
#include <set>
#include <map>
#include <iterator>
#include <iomanip>
#include <locale>

struct Employee {
	struct Name {
		std::string firstName;
		std::string lastName;
	} names;
	unsigned storeID {};
	unsigned salary {};
	unsigned daysWorked {};
	unsigned MonthlySales[12] {};
	unsigned totalSales {};
};

std::ostream& operator<<(std::ostream& os, const std::pair<unsigned, Employee>& emp) {
	const auto& [empID, e] {emp};

	os << empID << ", " << e.names.firstName << ", " << e.names.lastName << ", "
		<< e.storeID << ", " << e.salary << ", " << e.daysWorked << ", ";

	for (unsigned m = 0; m < 12; ++m)
		os << e.MonthlySales[m] << ' ';

	return os;
}

std::mt19937 rng(std::random_device {}());

std::string rndName() {
	constexpr unsigned minlen {8};
	constexpr unsigned maxlen {16};

	static const std::uniform_int_distribution<unsigned> strdist(minlen, maxlen);
	static const std::uniform_int_distribution<unsigned> chdist('a', 'z');
	std::string str(strdist(rng), 0);

	for (auto& ch : str)
		ch = static_cast<char>(chdist(rng));

	return str;
}

unsigned rndNum(unsigned first, unsigned last) {
	const std::uniform_int_distribution<unsigned> numdist(first, last);

	return numdist(rng);
}

std::map<unsigned, Employee> employees;

struct HighSrt {
	bool operator() (const unsigned& lhs, const unsigned& rhs) const
	{
		return employees[lhs].totalSales > employees[rhs].totalSales;
	}
};

struct LowSrt {
	bool operator() (const unsigned& lhs, const unsigned& rhs) const
	{
		return employees[lhs].totalSales < employees[rhs].totalSales;
	}
};

struct comma_facet : public std::numpunct<char> {
	explicit comma_facet(size_t group) : g(group) {}
	virtual char do_thousands_sep() const { return ','; }
	virtual std::string do_grouping() const { return std::string(1, static_cast<char>(g)); }
	size_t g {};
};

struct set000s {
public:
	explicit set000s(size_t grp) : group(grp) {}

private:
	size_t group {};

	friend std::ostream& operator<<(std::ostream& os, const set000s& grp) {
		os.imbue(std::locale(os.getloc(), new comma_facet(grp.group)));
		return os;
	}
};

int main()
{
	constexpr size_t noRows {10};
	constexpr size_t noMonths {12};
	constexpr size_t top_n {5};
	constexpr size_t bot_n {5};

	const auto dispSales {[](unsigned id) {
		std::cout << std::left << std::setw(10) << id << set000s(3);
		std::cout << std::right << std::setw(11) << employees[id].totalSales << set000s(0) << '\n';
	}};

	std::set<unsigned, HighSrt> highsale;
	std::set<unsigned, LowSrt> lowsale;

	for (size_t r = 0; r < noRows; ++r) {
		Employee emp;
		unsigned empID {};

		do {
			empID = rndNum(100'000, 999'999);
		} while (employees.find(empID) != employees.end());

		emp.names.firstName = rndName();
		emp.names.lastName = rndName();
		emp.storeID = rndNum(1'000, 9999);
		emp.salary = rndNum(20'000, 100'000);
		emp.daysWorked = rndNum(0, 21 * noMonths);

		for (unsigned m = 0; m < noMonths; ++m) {
			emp.MonthlySales[m] = emp.daysWorked * (emp.salary < 60'000 ? rndNum(1'000, 15'000) : rndNum(3'000, 20'000));
			emp.totalSales += emp.MonthlySales[m];
		}

		employees.emplace(empID, emp);
		highsale.insert(empID);
		lowsale.insert(empID);

		if (highsale.size() > top_n)
			highsale.erase(std::prev(highsale.end()));

		if (lowsale.size() > bot_n)
			lowsale.erase(std::prev(lowsale.end()));
	}

	std::cout << "Data by employee ID\n\n";

	for (const auto& emp : employees)
		std::cout << emp << '\n';

	std::cout << "\nThe top " << top_n << " sales are:\n\n";
	std::cout << "ID        Total Sales\n";

	for (const auto& id : highsale)
		dispSales(id);

	std::cout << "\n\nThe bottom " << bot_n << " sales are:\n\n";
	std::cout << "ID        Total Sales\n";

	for (const auto& id : lowsale)
		dispSales(id);

	std::cout << '\n';
}



Data by employee ID

272987, ufsucjqaryswrfj, dviviwqrru, 5575, 28015, 33, 426096 211398 304227 127380 492327 313335 217470 359073 167343 376926 269346 249183
345959, ebljixwongxete, oxzpczlitykj, 3096, 98957, 41, 579740 650834 295651 488146 508154 257234 758664 342678 407499 688472 325950 573631
388864, rvsqtnetuvrmaqey, gsmpoxkfpcc, 7052, 26590, 222, 2128536 326784 1518258 711510 2111664 2850036 1332666 662226 2304582 2430456 2678874 975024
444663, ehwqavwxjgwxiqg, gxvlvozt, 7525, 57320, 2, 24092 23232 15298 29264 18834 17240 17964 28514 29314 9820 2910 20680
497602, lesrngyo, xaxkgylatt, 5185, 71830, 187, 3136177 1406427 1285812 1356311 659362 1126301 2341801 2675596 3674737 3006399 2119458 1187263
664765, pahntbnafhmma, evzpodfcgahy, 4347, 77655, 203, 2557394 1561070 2518621 1404963 3082149 2762018 2860879 1452871 3000543 3408167 3564883 951055
768811, conttnmmjzezjgyq, imcsgqoucwmhks, 7189, 92178, 115, 1474070 2134170 1625870 2165565 2097830 1698090 1715800 706905 1907160 1322040 508760 523710
796378, egdqhfubopaicisg, wkovcimhnlrq, 5604, 71892, 245, 1896055 810950 3895500 1069915 3593660 2818970 3893050 1015770 2730280 1861755 2782220 1425410
875582, axbhcathwgleu, ilogqpwkhspvwlds, 2961, 37829, 220, 2792460 900680 1268080 3075160 2736140 1638120 431420 2278760 2257420 2808960 291720 2933700
939966, qgihuvok, uxsezvsghlrj, 6511, 91749, 78, 1190124 818298 346008 488514 1548768 563238 745212 1046292 857064 553176 1368198 776334

The top 5 sales are:

ID        Total Sales
664765     29,124,613
796378     27,793,535
497602     23,975,644
875582     23,412,620
388864     20,030,616


The bottom 5 sales are:

ID        Total Sales
444663        237,162
272987      3,514,104
345959      5,876,653
939966     10,301,226
768811     17,879,970

Last edited on
Topic archived. No new replies allowed.