I was trying to do a very common interview problem "Finding the max repeated word in a string " and could not find much resources in net for c/c++ implementation. So I coded it myself here.
I have tried to do most of the coding from scratch for better understanding.
Could you review my code and provide comments on my algorithm. Some people have suggested using hashtables for storing the count, but am not using hashtables here.
#include<stdafx.h>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<iostream>
using namespace std;
string word[10];
//splitting string into words
int parsestr(string str)
{
int index = 0;
int i = 0;
int maxlength = str.length();
int wordcnt = 0;
while(i < maxlength)
{
if(str[i]!= ' ')
{
word[index] = word[index]+str[i];
}
else
{
index++;//new word
wordcnt = index;
}
i++;
}
return wordcnt;
}
//find the max word count out of the array and return the word corresponding to that index.
string maxrepeatedWord(int wordcntArr[],int count)
{
int max = 0;
int index = 0;
for(int i=0;i<=count;i++)
{
if(wordcntArr[i] > max)
{
max = wordcntArr[i];
index = i;
}
}
return word[index];
}
void countwords(int count)
{
int wordcnt = 0;
int wordcntArr[10];
string maxrepeatedword;
for(int i=0;i<=count ;i++)
{
for(int j=0;j<=count;j++)
{
if(word[i]==word[j])
{
wordcnt++;
//word[j] = "";
}
else
{}
}
cout<<" word "<< word[i] <<" occurs "<< wordcnt <<" times "<<endl;
wordcntArr[i] = wordcnt;
wordcnt = 0;
}
maxrepeatedword = maxrepeatedWord(wordcntArr,count);
cout<< " Max Repeated Word is " << maxrepeatedword;
}
int main()
{
string str = "I am am am good good";
int wordcount = 0;
wordcount = parsestr(str);
countwords(wordcount);
}
Just for the sake of comparison, the most obvious way to do this is C++ is:
#include <map>
#include <string>
#include <iostream>
#include <sstream>
int main()
{
std::istringstream input("I am am am good good");
std::map<std::string, int> count;
std::string word;
decltype(count)::const_iterator most_common;
while (input >> word)
{
auto iterator = count.emplace(word, 0).first;
++iterator->second;
if (count.size() == 1 ||
iterator->second > most_common->second)
most_common = iterator;
}
std::cout << '\"' << most_common->first << "' repeated "
<< most_common->second << " times\n";
}
See it run here.
Notes:
map::emplace returns a pair<iterator,bool> indicating where the word & its count are in the map, and whether its newly inserted. We only care about where so capture emplace(...).first.
As we update the count, we check if that makes the word the most-common word seen so far. If so we copy the iterator to the local variable most_common, so we have a record of both the most commonly seen word so far and its count.
Some things you're doing that are worth thinking about:
word is a global variable - it's a good habit to pass things as function arguments unless it's terribly inconvenient, means the code can be reused more easily from async signal handlers or other threads, and it's more obvious in looking at a function call site what the inputs and outputs might be. As is, the call countwords(wordcount) makes it look like countwords' only input is the int wordcount.
fixed sized arrays: if you've more than 10 words, you're sunk. C++ Standard containers can grow on demand.
there are a few convenience functions you could use, such as std::string::operator+=(char) to append a char more concisely ala my_string += my_char;
Generally though, your code is quite sensible and shows a good understanding of iteration and problem solving, doing it all very low-level but that's good stuff to understand in a very hands-on way.
Code Snippet :
void mostRepeat(string words[], int n)
{
int hash[n]={0};
for(int j=0; j<n; j++)
{
for(int i=0; i<n; i++)
{
if(words[j]==words[i]) hash[j]++;
}
}
int maxi = hash[0];
int index = 0;
for(int i=0; i<n; i++)
{
if(maxi<hash[i])
{
maxi=hash[i];
index = i;
}
}
cout<<words[index]<<endl;
}
Full program : Link
import java.util.*;
public class StringWordDuplicates {
static void duplicate(String inputString){
HashMap<String, Integer> wordCount = new HashMap<String,Integer>();
String[] words = inputString.split(" ");
for(String word : words){
if(wordCount.containsKey(word)){
wordCount.put(word, wordCount.get(word)+1);
}
else{
wordCount.put(word, 1);
}
}
//Extracting of all keys of word count
Set<String> wordsInString = wordCount.keySet();
for(String word : wordsInString){
if(wordCount.get(word)>1){
System.out.println(word+":"+wordCount.get(word));
}
}
}
public static void main(String args[]){
duplicate("I am Java Programmer and IT Server Programmer with Java as Best Java lover");
}
}
Related
I'm pretty new to programming and recently started working with strings. In my mind, this idea should somewhat work, but I have no idea what's wrong.
So I go through the string, with simb++ (to find length of the word) and where++ (to find where in the string am I) until I find a space, where I compare with the longest word I've found so so far (temp) and if it's longer, I make it the longest and find starting point of the word (start). When the for(...) ends, I write the word in the last for()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string sentence;
string longest="";
int simb=0;
int temp=0;
int where=0;
int start=0;
cout<<"Input sentence"<<endl;
getline(cin,sentence);
for(int i=0 ; i<sentence.size() ; i++)
{
if(sentence[i]!=' ')
{
simb++;
where++;
}
if(sentence[i]==' ')
{
if(simb>temp)
{
where++;
simb++;
start=where-simb;
temp=simb;
}
simb=0;
}
}
for(int m=start ; m<=temp ; m++)
{
longest=longest+sentence[m];
}
cout<<"longest sentence"<<longest<<endl;
return 0;
}
There are a number of issues in your code:
if simb<=temp you don't increment where, you can just remove where completely and use i instead.
incrementing simb before calculating start results in start being 1 less than it should be
you don't check the length of last word in the string (assuming the string doesn't end with whitespace)
your final for loop goes from start to temp but should go from start to start + temp
Fixing these issues gives:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string sentence;
int simb = 0;
int temp = 0;
int start = 0;
string sentence = "test test2 test 3 test 4 foo longest";
for (int i = 0; i <= sentence.size(); i++)
{
if (i != sentence.size() && sentence[i] != ' ')
{
simb++;
}
else
{
if (simb > temp)
{
start = i - simb;
temp = simb;
}
simb = 0;
}
}
string longest = "";
for (int m = start; m < start + temp; m++)
{
longest = longest + sentence[m];
}
cout << "longest sentence: '" << longest << "'\n";
return 0;
}
Note that using std::istringstream would be much simpler:
#include <iostream>
#include <string>
#include <sstream>
int main()
{
std::string sentence = "test test2 test 3 test 4 foo longest";
std::string longest;
std::stringstream ss(sentence);
std::string word;
while (ss >> word)
{
if (word.length() > longest.length())
{
longest = word;
}
}
std::cout << "longest sentence: '" << longest << "'\n";
return 0;
}
You can try this:
1.first locate where the spaces are.
2.calculate the gap between the two consequent words/strings.
3.find the word which has the maximum gap.
4.the world which has the maximum gap will be the longest one.
It's not c++ specific you can try this with any language.
Here is the c++ example:
#include <iostream>
#include <string>
using namespace std;
int main(){
//to get the user input
cout<<"Enter a sentence:"<<endl;
string s;
getline(cin,s);
// here the old value refers to the last index having space
// gap is the difference betweeen latest index having space and the old value
// max stores the maximum gap
int old=0;
int max=0;
int gap=0;
//these two values store the starting and ending index of longest string
int startIndex;
int endIndex;
// This for loop determines the maximum gap and calculates the starting
// and ending index of the longest word.
for(int i=0;i<s.size();i++){
if(isspace(s[i])|| i==s.size()){
if((i-old)>gap){
max=(i-old);
startIndex=i-max;
endIndex=i;}
gap=(i-old);
old=i+1;}
}
cout<<"longest string in the sentence is:";
//here we are using the determined starting and ending indices to print the longest word
for(int i=startIndex;i<=endIndex;i++){
cout<<s[i];
}
return 0;
}
Say the strings is "Asah1234&^%736hsi)(91",
than storage 1234,736,91 in three arrays
In general,i want to put each continuous nums in each array.
Queations: how many arrays i will need,what's the size of each group of numbers,how to make the loop.
I want to write a fuction to do it.
#include<iostream>
using namespace std;
void splitString(string str)
{
string num;
for (int i = 0; i < str.length(); i++)
{
if (isdigit(str[i]))
num.push_back(str[i]);
}
cout << num << endl;
}
int countnum( string str)
{
string num;
int sum = 0;
for (int i = 0; i < str.length(); i++)
{
if (isdigit(str[i]))
sum++;
}
cout << sum << endl;
return 0;
}
int main()
{
const int MAXLEN = 100;
char str[MAXLEN];
printf("please enter strings:");
scanf_s("%s", str, MAXLEN);
splitString(str);
countnum( str);
return 0;
}
Maybe I have a misunderstanding here. Then please comment and I will delete the answer.
This is a standard task and will be solved with a regex. It is just the definition of a variable and initialzing this variable with its range constructor. So, a one-liner.
There is no further statement needed.
Please see:
#include <iostream>
#include <string>
#include <regex>
#include <vector>
std::regex re{ R"(\d+)" };
int main() {
// The input string with test data
std::string test{"Asah123&^%736hsi)(918"};
// Define a variable numbers and use the range constructor to put all data in it
std::vector numbers(std::sregex_token_iterator(test.begin(), test.end(), re), {});
// Show the result on the screen
for (const auto& n : numbers) std::cout << n << "\n";
return 0;
}
I am having problems with the following code once the string gets to around 24~ characters. It will run through the code just fine and calculate the correct amount of words in the string but it will error on strings containing more than a few words. You can try inputting your name in 3 or 4 times and it errors out for me. I ran the debug option and it shows the error at line 74 which is the last closing bracket for the main function.
#include <iostream>
using namespace std;
class WordCounter
{
private:
string tempInput;
int wordCount;
int arraySize;
char characterArray[];
public:
WordCounter()
{
tempInput = "";
wordCount = 0;
arraySize = 0;
}
void getCharString()
{
cout << "Enter the sentence you would like a word count for:\n";
getline(cin, tempInput);
}
void setArraySize()
{
arraySize = tempInput.length();
}
void convertStringToCharArray()
{
for(int counter = 0; counter < arraySize; counter++)
{
characterArray[counter] = tempInput[counter];
}
}
int countNumOfWords()
{
int charCount;
for(int counter = 0; counter < arraySize; counter++)
{
if(characterArray[counter] == '\n')
{
return 0;
}
if(characterArray[counter] == ' ')
{
charCount = 0;
}
else if(++charCount == 1)
{
wordCount++;
}
}
return wordCount;
}
};
int main()
{
WordCounter wordOne;
wordOne.getCharString();
wordOne.setArraySize();
wordOne.convertStringToCharArray();
int numberOfWords = wordOne.countNumOfWords();
cout << "The number of words in the sentence is " << numberOfWords << ".\n";
return 0;
}
If you want a function that count words in a string, where words are splited by whitespaces character, you can just use a regex :
#include <string>
#include <regex>
size_t countNumOfWords(std::string s) {
std::regex wordCountRegex("[^ ]+");
std::smatch matches;
size_t nb_words = 0;
while (std::regex_search(s, matches, wordCountRegex)) {
s = matches.suffix().str();
++nb_words;
}
return nb_words;
}
Or continue with the same code you had before :
int countNumOfWords(const std::string& s)
{
int charCount;
for(int counter = 0; counter < s.length(); counter++)
{
if(s[counter] == '\n')
{
return 0;
}
if(s[counter] == ' ')
{
charCount = 0;
}
else if(++charCount == 1)
{
wordCount++;
}
}
return wordCount;
}
However, if you want to continue using your code, you will have to make several modifications :
The field characterArray is never initialized, and no memory allocation is done. The value of characterArray ( which is a pointer to char ) is completely random, and accessing it through the subscript operator results in undefined behavior ( which means that the program could crash, or corrupt variables, or do nothing detectable, and that make debugging very hard ). You might want to add characterArray = new char[arraySize]; in the convertStringToCharArray() method
Speaking about converting std::string to char array, you might want to replace the code in the convertStringToCharArray() method by that : characterterArray = tempInput.c_str(). std::string::c_str() method return the internal value of the pointer in your std::string object, and points to the memory location where a char array has been allocated. You should not delete it
Based on the previous point, you might want to only use the std::string field, which has his own size information ( making arraySize field useless ) and his own char array ( making characterArray field useless ).
Regarding kmer https://en.wikipedia.org/wiki/K-mer
I am trying to find most frequent k-mers in a large fastq file. My plan was to use misra-gries algorithm to find most frequent k-mers, then searching each frequent k-mer's count in file with a second pass. Yet I don't think my algorithm is efficient enough. Here is my first draft below. I try to be memory efficient as possible.(program must not run out of memory)
I also found this DSK algorithm, yet this one is too hard for me to understand without seeing a simple implementation. http://minia.genouest.org/dsk/
Note: Also ID of each counter will be integers not strings, I am going to change it later in my final draft.
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
struct node {
string id;
int count;
};
void searchCount(vector <node>&memory, string line,int k) {
int count = 0;
string kMer;
for (int i = 0; i < memory.size(); i++) {
if (memory[i].id != "") {
for (int j = 0; j < line.length() - k + 1; j++) {
kMer = line.substr(j, k);
if (kMer == memory[i].id) {
count++;
}
}
}
memory[i].count = count;
count = 0;
}
}
int doWeHaveSpace(vector <node> memory) {
for (int i = 0; i < memory.size(); i++) {
if (memory[i].id == "") {
return i;
}
}
return -1;
}
void MisraGries(string element, vector <node> &memory) {
bool isHere = false;
int index;
for (int i = 0; i < memory.size(); i++) {
if (memory[i].id == element) {
isHere = true;
index = i;
}
}
if (isHere) {
memory[index].count++;
}
else {
int freeIndex = doWeHaveSpace(memory);
if (freeIndex+1) {
memory[freeIndex].count++;
memory[freeIndex].id = element;
}
else {
for (int i = 0; i < memory.size(); i++) {
if (memory[i].count != 0) {
memory[i].count--;
if (memory[i].count == 0) {
memory[i].id = "";
}
}
}
}
}
}
void filecheck(ifstream & input, string prompt) // this function checks and opens input files
{
string filename;
cout << "Please enter file directory and name for " << prompt << ": ";
do
{
getline(cin, filename);
input.open(filename.c_str());
if (input.fail())
cout << " wrong file directory. Please enter real directory. ";
} while (input.fail());
}
int main() {
int line = 1;
string filename;
ifstream input;
ofstream output;
string search;
vector <node> frequent(1000);
for (int i = 0; i < frequent.size(); i++) {
frequent[i].id = "";
frequent[i].count = 0;
}
int k = 30;
string kMer;
filecheck(input, "input file");
while (!input.eof())
{
getline(input, search); // it gets infos line by line to count lines
line++;
if (line == 3) {
for (int i = 0; i < search.length() - k + 1; i++) {
kMer = search.substr(i, k);
MisraGries(kMer, frequent);
}
line = -1;
}
}
return 0;
}
You can speed up your code by storing the most frequent k-mers in a hash table instead of an array. This way, you'll be able to process one k-mer in O(1) time (assuming that the length is constant) if it's already in the cache (if it's not, it would still require a linear pass, but it might give a big improvement on average).
You could also make it even faster if there're a lot of misses by keeping additional information in some kind of auxiliary data structure (like a priority queue) so that you can find the element with count = 0 and remove them without checking all other elements.
Taking into account that k is pretty small in your example, you could increase the size of your in-memory cache (a typical computer should easily keep a few millions of such strings in memory) so that there're less misses.
You could store even more data during the first pass by hashing k-mers (this way, you'll just need to store integers in memory instead of strings).
To sum it up, I'll recommend to make the cache larger (as long as it fits into memory) and use a more suitable data structure that supports fast lookups, like a hash table (std::unordered_map in C++).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I was asked this question in an interview:
Given an array with the input string, display the output as shown below
Input
INDIA
Output
INDA
****
*
I iterated through the array and stored each character as a key in std::map with value as number of occurrence. Later I iterate the map and print the asteriks and reduce the value in the map for each character.
Initially, I was asked not to use any library. I gave a solution which needed lot of iterations. For every character, iterate the complete array till the index to find previous occurrences and so on.
Is there any better way, e.g. better complexity, such as faster operation, by which this can be achieved?
Essentially what you are asking is how to implement map without using the STL code, as using some kind of data structure which replicates the basic functionality of map is pretty much the most reasonable way of solving this problem.
There are a number of ways of doing this. If your keys (here the possible characters) come from a very large set where most elements of the set don't appear (such as the full Unicode character set), you would probably want to use either a tree or a hash table. Both of these data structures are very important with lots of variations and different ways of implementing them. There is lots of information and example code about the two structures around.
As #PeterG said in a comment, if the only characters you are going to see are from a set of 256 8-bit chars (eg ASCII or similar), or some other limited collection like the upper-case alphabet you should just use an array of 256 ints and store a count for each char in that.
here is another one:
You can see it working HERE
#include <stdio.h>
int main()
{
int i,j=0,f=1;
char input[50]={'I','N','D','I','A','N','A','N'};
char letters[256]={0};
int counter[256]={0};
for(i=0;i<50;i++)
{
if(input[i])
counter[input[i]]++;
if(counter[input[i]]==1)
{
putchar(input[i]);
letters[j]=input[i];
j++;
}
}
putchar('\n');
while(f)
{
f=0;
for(i=0;i<j;i++)
if(counter[letters[i]])
{
putchar('*');
counter[letters[i]]--;
f=1;
}
else
{
putchar(' ');
}
putchar('\n');
}
return 0;
}
If the alphabet under consideration is fixed, it can be done in two passes:
Create an integer array A with the size of the alphabet, initialized with all zeros.
Create a boolean array B with size of the input, initialize with all false.
Iterate the input; increase for every character the corresponding content of A.
Iterate the input; output a character if its value it B is false and set its value in B to true. Finally, output a carriage return.
Reset B.
Iterate input as in 4., but print a star if if the character's count in A is positive, then decrease this count; print a space otherwise.
Output a carriage return; loop to 5 as long as there are any stars in the output generated.
This is interesting. You shouldnt use a stl::map because that is not a hashmap. An stl map is a binary tree. An unordered_map is actually a hash map. In this case we dont need either. We can use a simple array for char counts.
void printAstr(std::string str){
int array[256] ;// assumining it is an ascii string
memset(array, 0, sizeof(array));
int astrCount = 0;
for(int i = 0; i < str.length()-1; i++){
array[(int) str[i]]++;
if(array[(int) str[i]] > 1) astrCount++;
}
std::cout << str << std::endl;
for(int i = 0; i < str.length()-1;i++) std::cout << "* ";
std::cout << std::endl;
while(astrCount != 0){
for(int i= 0; i< str.length() - 1;i++){
if(array[(int) str[i]] > 1){
std::cout << "* ";
array[(int) str[i]]--;
astrCount--;
}else{
std::cout << " ";
}
}
std::cout << std::endl;
}
}
pretty simple just add all values to the array, then print them out the number of times you seem them.
EDIT: sorry just made some logic changes. This works now.
The following code works correctly. I am assuming that you can't use std::string and take note that this doesn't take overflowing into account since I didn't use dynamic containers. This also assumes that the characters can be represented with a char.
#include <iostream>
int main()
{
char input[100];
unsigned int input_length = 0;
char letters[100];
unsigned int num_of_letters = 0;
std::cin >> input;
while (input[input_length] != '\0')
{
input_length += 1;
}
//This array acts like a hash map.
unsigned int occurrences[256] = {0};
unsigned int max_occurrences = 1;
for (int i = 0; i < input_length; ++i)
{
if ((occurrences[static_cast<unsigned char>(input[i])] += 1) == 1)
{
std::cout<< " " << (letters[num_of_letters] = input[i]) << " ";
num_of_letters += 1;
}
if (occurrences[static_cast<unsigned char>(input[i])] > max_occurrences)
{
max_occurrences = occurrences[static_cast<unsigned char>(input[i])];
}
}
std::cout << std::endl;
for (int row = 1; row <= max_occurrences; ++row)
{
for (int i = 0; i < num_of_letters; ++i)
{
if (occurrences[static_cast<unsigned char>(letters[i])] >= row)
{
std::cout << " * ";
}
else
{
std::cout << " ";
}
}
std::cout << std::endl;
}
return 0;
}
The question is marked as c++ but It seems to me that the answers not are all quite C++'ish, but could be quite difficult to achieve a good C++ code with a weird requirement like "not to use any library". In my approach I've used some cool C++11 features like in-class initialization or nullptr, here is the live demo and below the code:
struct letter_count
{
char letter = '\0';
int count = 0;
};
int add(letter_count *begin, letter_count *end, char letter)
{
while (begin != end)
{
if (begin->letter == letter)
{
return ++begin->count;
}
else if (begin->letter == '\0')
{
std::cout << letter; // Print the first appearance of each char
++begin->letter = letter;
return ++begin->count;
}
++begin;
}
return 0;
}
int max (int a, int b)
{
return a > b ? a : b;
}
letter_count *buffer = nullptr;
auto testString = "supergalifragilisticoespialidoso";
int len = 0, index = 0, greater = 0;
while (testString[index++])
++len;
buffer = new letter_count[len];
for (index = 0; index < len; ++index)
greater = max(add(buffer, buffer + len, testString[index]), greater);
std::cout << '\n';
for (int count = 0; count < greater; ++count)
{
for (index = 0; buffer[index].letter && index < len; ++index)
std::cout << (count < buffer[index].count ? '*' : ' ');
std::cout << '\n';
}
delete [] buffer;
Since "no libraries are allowed" (except for <iostream>?) I've avoided the use of std::pair<char, int> (which could have been the letter_count struct) and we have to code many utilities (such as max and strlen); the output of the program avobe is:
supergaliftcod
**************
* ******* *
* *** *
* *
*
*
My general solution would be to traverse the word and replace repeated characters with an unused nonsense character. A simple example is below, where I used an exclamation point (!) for the nonsense character (the input could be more robust, some character that is not easily typed, disallowing the nonsense character in the answer, error checking, etc). After traversal, the final step would be removing the nonsense character. The problem is keeping track of the asterisks while retaining the original positions they imply. For that I used a temp string to save the letters and a process string to create the final output string and the asterisks.
#include <iostream>
#include <string>
using namespace std;
int
main ()
{
string input = "";
string tempstring = "";
string process = "";
string output = "";
bool test = false;
cout << "Enter your word below: " << endl;
cin >> input;
for (unsigned int i = 0; i < input.length (); i++)
{ //for the traversed letter, traverse through subsequent letters
for (unsigned int z = i + 1; z < input.length (); z++)
{
//avoid analyzing nonsense characters
if (input[i] != '!')
{
if (input[i] == input[z])
{ //matched letter; replace with nonsense character
input[z] = '!';
test = true; //for string management later
}
}
}
if (test)
{
tempstring += input[i];
input[i] = '*';
test = false; //reset bool for subsequent loops
}
}
//remove garbage symbols and save to a processing string
for (unsigned int i = 0; i < input.size (); i++)
if (input[i] != '!')
process += input[i];
//create the modified output string
unsigned int temp = 0;
for (unsigned int i = 0; i < process.size (); i++)
if (process[i] == '*')
{ //replace asterisks with letters stored in tempstring
output += tempstring[temp];
temp++;
}
else
output += process[i];
//output word with no repeated letters
cout << output << endl;
//output asterisks equal to output.length
for (unsigned int a = 0; a < output.length (); a++)
cout << "*";
cout << endl;
//output asterisks for the letter instances removed
for (unsigned int i = 0; i < process.size (); i++)
if (process[i] != '*')
process[i] = ' ';
cout << process << endl << endl;
}
Sample output I received by running the code:
Enter your word below:
INDIA
INDA
****
*
Enter your word below:
abcdefgabchijklmnop
abcdefghijklmnop
****************
***
It is possible just using simple array to keep count of values.
#include<iostream>
#include<string>
using namespace std;
int main(){
string s;
char arr[10000];
cin>>s;
int count1[256]={0},count2[256]={0};
for(int i=0;i<s.size();++i){
count1[s[i]]++;
count2[s[i]]++;
}
long max=-1;
int j=0;
for(int i=0;i<s.size();++i){
if(count1[s[i]]==count2[s[i]]){ //check if not printing duplicate
cout<<s[i];
arr[j++]=s[i];
}
if(count2[s[i]]>max)
max=count2[s[i]];
--count1[s[i]];
}
cout<<endl;
for(int i =1; i<=max;++i){
for(int k=0;k<j;++k){
if(count2[arr[k]]){
cout<<"*";
count2[arr[k]]--;
}
else
cout<<" ";
}
cout<<endl;
}
}