Metoda mai eficienta pentru aflarea frecvenței literelor dintr-un string

Salut, am o tema pentru facultate, si caut sa folosesc o metoda cat mai eficienta pentru o chestie.

Am un text de exemplu:
data.in : " vasile are mere "
data.out: “vasilerm” “12111411”

Numerele reprezinta frecventa literelor ( numarul de aparitii in propozitie ) .
Eu am facut ceva pe o structura (am nev de structura pentru ca o lucrez cu lista), dar nu arata tocmai “estetic” pentru ca am folosit prea multe bucle.

Daca cineva are inspiratie de moment si vrea sa ma ajute cu un indiciu, este bine venit.
Multumesc !

Pune codul tău, să vedem ce ai făcut până acum (eventual specifică și limbajul)

În PHP poți folosi array_count_value.

<?php
function counter($string) {
	$chars = str_split($string);
	$holder = array();
	foreach($chars as $char) {
			if(isset($holder[$char])) {
			$holder[$char]++;
		} else {
			$holder[$char] = 1;
		}
	}
return $holder;
}

print_r(counter('vasile are mere'));

Output:

Array
(
    [v] => 1
    [a] => 2
    [s] => 1
    [i] => 1
    [l] => 1
    [e] => 4
    [ ] => 2
    [r] => 2
    [m] => 1
)

Ramane de scos space-ul de pe acolo.

sau asa, tot php

$string = "vasile are mere";

$split = str_split($string, 1);
print_r(array_count_values($split));

output

Array
(
    [v] => 1
    [a] => 2
    [s] => 1
    [i] => 1
    [l] => 1
    [e] => 4
    [ ] => 2
    [r] => 2
    [m] => 1
)

le. acum am vazut ca @iamntz deja iti daduse solutia :smile:

1 Like

Poti face $split = str_split(str_replace(' ', '',$string), 1); ca sa scapi de spatiu.

Eu habar nu aveam ce output da metoda iamntz, dar
daca e pentru facultate eu iti propun sa folosesti varianta putin mai desfacuta. In principiu trebuie sa ii arati ca intelegi logica din spatele codului. Asa sa rezolvi totul cu o functie, nu e prea teachy :stuck_out_tongue:

1 Like

data.out e gresit in exemplul tau.
vasilerm 12111421 sunt doi de r
Cred ca folosesti C.
Ai putea salva aparitia literelor intr-un vector de intregi.
vector['a'] = 1; bla bla
Ai o parcurgere sa formezi “vasilerm” si in acelasi timp sa contorizezi frecventa in vector(index based fata de lista unde ai un for pentru fiecare litera).
Si inca o parcurgere sa afisezi frecventa.

De dragul de a avea și alte limbaje aici,

C#

    var dataIn = " vasile are mere ";
    var frequencies = new Dictionary<char, int>();
  
    var characters = dataIn.ToCharArray();
    foreach (var c in characters)
    {
        if (frequencies.ContainsKey(c))
          frequencies[c] += 1;
        else
          frequencies.Add(c, 1);
    }

Și în Java ar arăta asemănător, doar că ai folosi clasa HashMap în loc de Dictionary; bineînțeles, diferă și interfața, deci put în loc de Add, etc.

Oricum, conceptul e același - ia fiecare literă în parte și pune-le alături de frecvențele lor într-un HashMap (sau Dictionary sau array sau oricum i-ar zice limbajul tău). Dacă nu ai luxul ăsta și ești în C, atunci poți folosi două liste, una pentru litere, iar alta pentru frecvențe; aici e important să păstrezi același index pentru ambele liste, e.g.:

char[] characters = ['v', 'a', 's', ...]
int[] frequencies  = [1, 2, 1, ...]

Dacă nu ai luxul spațiului, ai putea folosi o singură listă pentru ambele informații. Asta presupune, însă, că poți reprezenta fiecare literă printr-un număr, e.g. șirul tău de caractere vine în ASCII. Așa ai putea face convenția că în lista ta, indexul reprezintă valoarea numerică a literei, iar valoarea reprezintă frecvența literei respective.

int[] frequencies = [..., 2, 0, 0, 0, ...]

// "a" în tabelul ASCII e la 97, deci frequencies[97] = 2
2 Likes

O sa postez si codul cand ajung acasa, nu am specificat limbajul, scuze pentru asta. Lucrez in C++ .
Eram la munca atunci si am scris in graba.

E si cod C mura in gura in pagina aia.

e acolo un tabel, depinde ce intelegi prin eficienta, daca e timp, memorie…

1 Like