Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Igor Pereira

Contar caracteres iguais

Recommended Posts

Amigos,

 

Estou penando....

a idéia é abrir o arquivo, contar os caracteres, e desses caracteres achar a frequencia relativa de cada caracter.

Ex:. "casa" total de 4 caracteres "a" = 2 =50% , "c"=1 = 25%, "s"=1 = 25%.

 

a porcentagem eu faço, a minnha dificuldade é comparar esses caracteres e contar os caracteres iguais.. algum help? abaixo o inicio do codigo.

<?php
// abrindo arquivo determinado
 $conteudo = file_get_contents("criptografia/teste.txt","r");
// quantidade de caracteres do arquivo 
$caracteres += strlen($conteudo); 
echo "Caracteres: " . $caracteres ."<br />"; 
 for ($i = 0; $i < $caracteres; $i++)
 {  
	   //aqui eu quero fazer frequencia relativa dos caracteres...
 }  
 ?>

Compartilhar este post


Link para o post
Compartilhar em outros sites

<?php 

//array multidimensional

$alfabeto=array( array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',  'i',  'j',  'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'y', 'w', 'z'), array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) );

//print_r($alfabeto); //debug

//echo "<br />".$alfabeto[1][22]."<br />"; //debug

$caracteres= "abcaaa"; //cria string
$caracteres= strtolower($caracteres); //tudo para letras minúsculas
$n_caracteres= strlen($caracteres);  //conta caracteres

for ($i=0; $i<$n_caracteres; $i++) //loop
 {  
	 
     if($caracteres[$i]==$alfabeto[0][0]){//loop na letra a
	     
			 $alfabeto[1][0]+=1;//se o caractere for igual ao caract. do array, entra nesse if e soma 1 a variavel $letra_a 
		   $letra_a= $alfabeto[1][0];
  
      }

}

echo $letra_a; //imprime 4

//agora é só repetir para cada letra do alfabeto, deve ter um jeito mais fácil, é uma questão de estudar o script

?>

Não sei se é a melhor forma de fazer isso, mas ...

 

Acho que o pulo do gato é trabalhar com array multidimensional

Compartilhar este post


Link para o post
Compartilhar em outros sites

Faça um loop, verificando todas as letras que você deseja com a função substr_count().

Exemplo:

 

<?php
$array = array('a','b','c');
foreach ($array as $letra) {
    $chave = 'letra'.$letra;
    $$chave = substr_count($string, $letra);
}
echo $letraa.'<br />';
echo $letrab.'<br />';
echo $letrac;
?>

Acho que é isso, James Brown.

Compartilhar este post


Link para o post
Compartilhar em outros sites

<?php 

//array multidimensional

$alfabeto=array( array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',  'i',  'j',  'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'y', 'w', 'z'), array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) );

//print_r($alfabeto); //debug

//echo "<br />".$alfabeto[1][22]."<br />"; //debug

$caracteres= "abcaaa"; //cria string
$caracteres= strtolower($caracteres); //tudo para letras minúsculas
$n_caracteres= strlen($caracteres);  //conta caracteres

for ($i=0; $i<$n_caracteres; $i++) //loop
 {  
	 
     if($caracteres[$i]==$alfabeto[0][0]){//loop na letra a
	     
			 $alfabeto[1][0]+=1;//se o caractere for igual ao caract. do array, entra nesse if e soma 1 a variavel $letra_a 
		   $letra_a= $alfabeto[1][0];
  
      }

}

echo $letra_a; //imprime 4

//agora é só repetir para cada letra do alfabeto, deve ter um jeito mais fácil, é uma questão de estudar o script

?>

Não sei se é a melhor forma de fazer isso, mas ...

 

Acho que o pulo do gato é trabalhar com array multidimensional

 

Estava seguindo essa mesma linha de pensamento, mesmo achando q deve ter uma maneira mais convencional, afinal, essa maneira vou ter q fazer 26x loop.

 

estou tentando trabalhar no raciocinio do h4x0r, mas não entendi a linha:

$chave = 'letra'.$letra;

 

não entendi a saída, neste caso iria sair as letras existentes,e a sua qntde?

 

ficaria assim?

$alfabeto = array('a','b','c');
foreach ($alfabeto as  $letra) {
	$chave = '???'.$letra;
	$chave = substr_count($conteudo,$letra);
	
}
echo ???;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Faça melhor...

 

<?php
$array = array('a','b','c');
foreach ($array as $letra) {
    $letras[$letra] = substr_count($string, $letra);
}
echo $letras['a'].'<br />';
echo $letras['b'].'<br />';
echo $letras['c'];
?>

Deu pra entender agora? É só um método de identificação da letra.

 

Exemplo prático:

 

<?php
$array = array('a','b','c');
$string = 'Eu adoro galinha - bbbbbbbbbbbbbbbbbbbbbbbbbbbb';
foreach ($array as $letra) {
    $letras[$letra] = substr_count($string, $letra);
}
echo $letras['a'].'<br />';
echo $letras['b'].'<br />';
echo $letras['c'];
?>

Resultado:

 

3

28

0

Até mais.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Putz,

 

Que show!!! me salvou de quase 300 linhas de codigo rsrsrs....

 

agora deu pra entender, pra nao dizer que copiei seu codigo deixei assim:

foreach ($alfabeto as  $letra) {
	//$letras[$letras] = 'letra'.$letra;
	$letras[$letra] = substr_count($conteudo,$letra);
	
}
	$i = 0;
	while  ($i < 26)  {
	echo $alfabeto[$i]."-" .$letras[$alfabeto[$i]].'<br />';
	
	$i++;
	}

Compartilhar este post


Link para o post
Compartilhar em outros sites

ao final para escrever o resultado já com a frequencia relativa ficou assim:

 

//array do alfabeto
$alfabeto =  array( 'a', 'b', 'c', 'd','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','y','x','w','z');
//percorre o alfabeto
foreach ($alfabeto as  $letra) {
	//fazendo um loop com as letras do conteudo e a contagem com a funcao substr_count
	$letras[$letra] = substr_count($conteudo,$letra);
}
	$i = 0;
	// percorre o alfabeto e escreve as letras e a sua qtde dentro do conteudo do arquivo
	while  ($i <= 26)  {
			$FR = ($letras[$alfabeto[$i]] / $caracteres)*100;
			echo $alfabeto[$i]." = ".$letras[$alfabeto[$i]]." F.R = ".$FR.'%<br />';
			$i++;
	}
a escrita ficou:

a = 4 F.R = 9.7560975609756%

b = 0 F.R = 0%

c = 1 F.R = 2.4390243902439%

d = 1 F.R = 2.4390243902439%

e = 6 F.R = 14.634146341463%

f = 0 F.R = 0%

g = 1 F.R = 2.4390243902439%

h = 0 F.R = 0%

i = 3 F.R = 7.3170731707317%

.

.

.

 

a

 

Mas preciso manipular os resultados individualmente, como posso criar um novo array com o resultado? para assim poder excluir os caracteres sem frequencia, e poder fazer operações entre eles.

Compartilhar este post


Link para o post
Compartilhar em outros sites

<?php
$str = 'As pessoas deveriam ler mais o manual do PHP';

var_dump( count_chars( $str , 1 ) );

 

Saída:

array(17) {
 [32]=>
 int(8)
 [65]=>
 int(1)
 [72]=>
 int(1)
 [80]=>
 int(2)
 [97]=>
 int(5)
 [100]=>
 int(2)
 [101]=>
 int(4)
 [105]=>
 int(2)
 [108]=>
 int(2)
 [109]=>
 int(3)
 [110]=>
 int(1)
 [111]=>
 int(3)
 [112]=>
 int(1)
 [114]=>
 int(2)
 [115]=>
 int(5)
 [117]=>
 int(1)
 [118]=>
 int(1)
}

Usando array_walk():

<?php
function frequencia( $v , $k , $t ){
	printf( "A letra %c apareceu %d ou %.02f%% do total de %d\n" , $k , $v , $v * 100 / $t , $t );
}

$str = 'As pessoas deveriam ler mais o manual do PHP';
$arr = count_chars( $str , 1 );

array_walk( $arr , 'frequencia' , strlen( $str ) );

 

Saída:

A letra apareceu 8 ou 18.18% do total de 44

A letra A apareceu 1 ou 2.27% do total de 44

A letra H apareceu 1 ou 2.27% do total de 44

A letra P apareceu 2 ou 4.55% do total de 44

A letra a apareceu 5 ou 11.36% do total de 44

A letra d apareceu 2 ou 4.55% do total de 44

A letra e apareceu 4 ou 9.09% do total de 44

A letra i apareceu 2 ou 4.55% do total de 44

A letra l apareceu 2 ou 4.55% do total de 44

A letra m apareceu 3 ou 6.82% do total de 44

A letra n apareceu 1 ou 2.27% do total de 44

A letra o apareceu 3 ou 6.82% do total de 44

A letra p apareceu 1 ou 2.27% do total de 44

A letra r apareceu 2 ou 4.55% do total de 44

A letra s apareceu 5 ou 11.36% do total de 44

A letra u apareceu 1 ou 2.27% do total de 44

A letra v apareceu 1 ou 2.27% do total de 44

 

http://forum.imasters.com.br/public/style_emoticons/default/seta.gif count_chars()

http://forum.imasters.com.br/public/style_emoticons/default/seta.gif array_walk()

Compartilhar este post


Link para o post
Compartilhar em outros sites

Excelente solução João, mas tem dois pontos que poderiam melhorar, já que fogem ligeiramente ao contexto da dúvida original.

 

Primeiro é que a função está considerando também os espaços em branco, sinais de pontuação e etc. O comportamento é o esperado, mas nada disso, ao que a dúvida sugere, poderia ser utilizado para o proposto.

 

Segundo é que a função é case-sensitive. Programaticamente, A é diferente de a, mas, novamente, para o contexto, acredito que o melhor seria que fossem consideradas como iguais, já que A vai ser A, não importa como.

 

Fiz as alterações abaixo:

 

<?php

function frequencia( $v , $k , $t ) {

   printf( "A letra <strong>%c</strong> apareceu <strong>%d</strong> ou <strong>%.02f%%</strong> do total de <strong>%d</strong>\n<br />",
	$k , $v , $v * 100 / $t , $t );
}

$str = 'A casa';
$arr = count_chars( preg_replace( '/\W/', '', strtolower( $str ) ), 1 );

array_walk( $arr, 'frequencia', strlen( $str ) );

Adicionei uns negritos pra afrescurar um pouco. :P

Compartilhar este post


Link para o post
Compartilhar em outros sites

já que fogem ligeiramente ao contexto da dúvida original.

 

Mas eu não quis resolver o problema, apenas mostrei que, se as pessoas lerem o manual, verão que 90% da solução já existe.

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não quis, mas acabou resolvendo ^_^

 

Só apontei duas coisas que notei.

Compartilhar este post


Link para o post
Compartilhar em outros sites

E... quem sabe, sabe!!!

 

estou em um nivel de conhecimento bem mais abaixo, estarei lendo sim sobbre essas funcoes no manual, que até entao desconhecia. Vou dar uma estudada nessa função tbm q vcs fizeram, porque olhando em primeiro momento nao sei como manipular o results individualmente para fazer operações... caso n consiga posto de novo...

 

 

O objetivo final é criptografar um arquivo rs,, "manualmente", conccluido posto todo o script. de codificacao e decodificacao.

 

--------------- Ponto de Mesclagem ---------------

 

Do codigo acima ao invés do printf salvei as informacoes em um vetor.porem queria utilizar esse vetor fora funcao. como faço?

 

function frequencia( $qtde , $char , $qtde_total )
  {   

	 $contagem[] = array ($char , $valor , $qtde_total);
	 //print_r($contagem);
	return $contagem; //assim?
	 }

bom galeria o objetivo é fazer uma codificação aritmetica, mas nao to conseguindo, tem um codigo em python como exemplo aqui.. http://pt.wikipedia.org/wiki/Codifica%C3%A7%C3%A3o_aritm%C3%A9tica

mas queria eu continuar o q estavamos fazendo. portanto acho q o proximo passo e construir um vetor fora da funcao frequencia contendo o vetor das info frequencia. para que eu possa fazer os intervalos coforme é o algoritmo no link da wiki. e depois fazer os intervalos dos caracteres para fazer a codificacao similar a imagem abaixo. alguma ajuda?

Imagem Postada

 

--------------- Ponto de Mesclagem ---------------

 

estou tentaado usar o array_map ao inves do array_walk, não estou conseguindo, porem sei q o array_map retorna um valor da funcao diferente do array_walk.... algum ajuda?

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.