0

Suppose my input is:

marcel bentok tanaka

Output should be

m-1,a-4,r-1,c-1,l-1,e-2,l-1,b-1,n-2,t-2,o-1,k-2

I don’t want to count spaces and don’t want to use dict or import functions.How can I achieve this in the easiest way possible? Please do help. I tried searching online,but all of them display output in dict format i.e., {m-1,a-4,r-1,c-1,l-1,e-2,l-1,b-1,n-2,t-2,o-1,k-2} I am just beginning to learn coding. So please help. Thanks in advance.

I tried this

def letter_count(name)
for char in name:
        print(f"{char}-{name.count(char)}")

But this isn't working for input bob

  • [this](https://stackoverflow.com/questions/1155617/count-the-number-occurrences-of-a-character-in-a-string) might help – Aven Desta Apr 01 '20 at 17:56
  • Yes just started to learn about list,tuple. But I don't want the output in list format either i.e.,[m-1,a-4,r-1,c-1,l-1,e-2,l-1,b-1,n-2,t-2,o-1,k-2]. I want it as m-1,a-4,r-1,c-1,l-1,e-2,l-1,b-1,n-2,t-2,o-1,k-2. How to do that? Can you please tell @Babydesta – Shilpa Srinath Apr 01 '20 at 17:57
  • But in that link it just displays the count of each character we give as input. But I want the count of all characters in this form i.e, b-2,o-1 @Babydesta – Shilpa Srinath Apr 01 '20 at 17:59
  • 2
    I have not down voted anyone's answer. I am a new user I can't down vote at the first place @Babydesta – Shilpa Srinath Apr 01 '20 at 18:09
  • I want to do this in functions method and also I don't want to declare input inside the code instead I want to define a func say def count_freq(name) and give the input name after executing the program. How to do that? @Babydesta – Shilpa Srinath Apr 01 '20 at 18:32
  • @ShilpaSrinath I have updated the answer to reflect the input you requested – Victor Silva Apr 01 '20 at 19:24

4 Answers4

1

Still using dictionaries but in a simpler fashion this is O(n^2)

def count_freq(name):
    x = dict()

    name = name.replace(' ', '')

    for i in name:
        if i in x.keys():
            x[i] += 1
        else:
            x[i] = 1

    b = [f"{k}-{v}" for k, v in x.items()]
    print(",".join(b))

name = input("Please insert your input: ")
count_freq(name)

Here's a O(n) solution in a beginner's fashion:

def count_freq(name):
    x = dict()
    name = name.replace(' ', '')

    for i in name:
        try:
            x[i] += 1
        except:
            x[i] = 1

    b = [f"{k}-{v}" for k, v in x.items()]
    print(",".join(b))

name = input("Please insert your input: ")
count_freq(name)

Execution time analysis:

#input is 'marcel bentok tanaka'
#string format no-print
theo 9 µs ± 1.37 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
**vn2  4.39 µs ± 157 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)**
vn   6.78 µs ± 1.34 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

#no string format (counts only)
theo 5.74 µs ± 953 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
**vn2  2.42 µs ± 30 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)**
vn   3.66 µs ± 668 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

#input is a really long text
#string format no-print
theo 20.8 µs ± 1.43 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
vn2  106 µs ± 21.9 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
**vn   6.06 µs ± 1.04 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)**

#no string format (counts only)
theo 16.6 µs ± 576 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
vn2  83 µs ± 21.2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
**vn   3.22 µs ± 197 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)**
Victor Silva
  • 306
  • 2
  • 15
  • Or you could just say if i not in x.keys(): x[i] = a.count(x) – Theo Apr 01 '20 at 18:04
  • @Theo That's not a good option as the algorithm is n^3 if you call count. – Victor Silva Apr 01 '20 at 18:13
  • A suggestion to improve my case to O(n) would be replace the i in x.keys() by a try catch, as this would be a O(1) operation done n times, thus O(n). – Victor Silva Apr 01 '20 at 18:15
  • Your first for loop with the edit you made is o(n) and your second for loop is o(n) aswell. – Theo Apr 01 '20 at 18:19
  • I want to do this in functions method and also I don't want to declare input inside the code instead I want to define a func say def count_freq(name) and give the input name after executing the program. How to do that? @VictorSilva – Shilpa Srinath Apr 01 '20 at 18:31
0

you can try this:

def count_freq(name):
    name = name.replace(' ','')
    output = ''
    for char in set(name):
        output += (char + '-' + str(name.count(char)) + ',')
    return output

name = input('insert name:')
print(count_freq(name))
gekigek99
  • 303
  • 3
  • 17
0

Make it a dict, and then convert the dict to a string in any way you want. For example,

counts = {}
for char in "abcdefghijklmnopqrstuvwxyz":
    counts[char] = myString.count(char)
for key in counts.keys():
    print(f"{key}-{counts[char]}")

Or, if you really hate dicts then just skip it:

for char in "abcdefghijklmnopqrstuvwxyz":
    print(f"{char}-{myString.count(char)}")

If you don't want to display those with zero occurences, replace the last part of the dict solution with:

for key in counts.keys():
    if counts[char]:
        print(f"{key}-{counts[char]}")
Theo
  • 613
  • 4
  • 22
  • @Ch3steR How? At least, the middle one... If the length of the string doubles, then count should take twice as long... Where do you get O(n^2) – Theo Apr 01 '20 at 18:06
  • one could also use set(myString) instead of the whole alphabet – Victor Silva Apr 01 '20 at 18:07
  • @Ch3steR you clearly don't know how big O notation works... No matter how long the string, there are still 26 letters in the alphabet. Therefore, the 26 is part of the big O. If the length of the alphabet changed relating to the length of the string, then it would be O(n^2) lol – Theo Apr 01 '20 at 18:09
  • @Ch3steR the n in big O is the length of the string, how does the for loop have to iterate N times? It iterates 26 times. – Theo Apr 01 '20 at 18:10
  • @Ch3steR Not how big O notation works dude. Yes, count is O(n). Executing an O(n) function 26 times doesn't make it O(n^2) right? – Theo Apr 01 '20 at 18:15
  • @Ch3steR Good job deleting your comments after being proven wrong bud... Really making your case here. – Theo Apr 01 '20 at 18:20
  • 1
    @Theo LOL. So much hate in one person. But still, this answer can be improved. Look at `Counter`.Using it you don't need to iterate 26 times through your string. It does the job in one pass. good luck ;) I wasn't complaining about your answer, was helping to make it better. – Ch3steR Apr 01 '20 at 18:24
  • @Ch3steR You claimed my code was O(n^2). My code is O(n). I was demonstrating it to yuo. Thank you for ignoring my reasoning I guess. – Theo Apr 01 '20 at 18:28
  • I want to do this in functions method and also I don't want to declare input inside the code instead I want to define a func say def count_freq(name) and give the input name after executing the program. How to do that?@Theo – Shilpa Srinath Apr 01 '20 at 18:28
  • 1
    @Theo Yeah I know agreed. If you are interested in improving the answer further and doing it in single pass instead of 26 passes use [`Counter`](https://docs.python.org/3.8/library/collections.html#collections.Counter) which is way more efficient or mimic the same functionality with `dict.fromkeys` or use `defaultdict(int)`. – Ch3steR Apr 01 '20 at 18:34
  • 2
    @Theo So, for the input given your code is not O(n). Suppose n = len(a), where a is the input, or 20. Your approach is doing 26x20 or O(n^2). Now for the general alphabetic case your approach is O(n), because your approach is O(n * m), where m is the size of your dict, or 26. If we consider that we don't know the input characters, your approach is O(n^2), since m has an arbitrary size (although m is finite). My first case is O(n^2) because it is the *worst* case, where we traverse keys() with all chars. I would suppose it could be reduced to O(n log n) if we consider i in x.keys() as O(log n) – Victor Silva Apr 01 '20 at 18:49
  • Small typo I noticed. replace `print(f"{key}-{counts[char]}")` with `print(f"{key}-{counts[key]}")`. [link](https://repl.it/repls/StrongAdorableSpheres) – Ch3steR Apr 01 '20 at 19:18
  • @VictorSilva 26 considering on lower-case alphabets when considering all printable ASCII values(`string.printable`) it scales to `100*N` times. `O(100*N)` is equivalent to `O(N)`. Making it `O(N)` algo. This problem can be literally done in `O(1*N)` time. – Ch3steR Apr 01 '20 at 19:22
  • 1
    @Ch3steR that is why I also expanded on the *If we consider that we don't know the input characters*. We know that if we do not limit what characters are in the input then this is clearly a O(n^2) solution. – Victor Silva Apr 01 '20 at 19:26
  • 1
    @VictorSilva Not really `O(n^2)` but it makes it `O(m*n)` like you mentioned according to big-O. When `m` and `n` are very large. It's equivalent to `O(n^2)` I agree. – Ch3steR Apr 01 '20 at 19:29
0

This is similar to gekigek99's answer


def letter_count(name):
    name = string.replace(' ','') # this removes the spaces
    name_set = set(new_name) # this creates set of the characters
    for char in name_set:
        count = str(name.count(char)) # counts how many times $char appeared in $name
        print(char + '-' + count + ',', end = '')

#example
name = 'marcel bentok tanaka'
letter_count(name)
Aven Desta
  • 2,114
  • 12
  • 27