Mittels FOR-Schleife Alphabet erzeugen, abhängig von INT[] Wert

Mik3e

Erfahrenes Mitglied
Mahlzeit zusammen!

Habe folgendes Problem:
Es gibt eine Anzahl von n-Elementen, die jeweils als Datensatz in einer DB gespeichert werden. Jedes Element hat eine Bezeichnung. Standardmäsig ist diese Bezeichnung 1 bis n.

Nun kann der User aber auch auswählen, dass die Elemente alphabetisch benannt werden sollen (A-nn). Also : A,B,C.... AA, AB, AC usw.

Das kann man eigentlich ganz elegant mit einer for() Schleife lösen:
PHP:
for ($i = A; $i!='AA'; $i++) {
    echo $i.'<br>';
}
// Liefert A->Z


Das eigentliche Problem ist nun, dass ich den Limiter in der FOR-Schleife (hier 'AA') als Integerwert vorliegen haben (die Anzahl der Reihen).

Ich brauche nun eine Möglichkeit, die anzahl der Reihen (INT[]) auf das Alphabet zu mappen..

Sollte dann so funktionieren (gewünschte Lösung):
PHP:
$reihenanzahl=26;
for ($i = A; $i!=$reihenanzahl; $i++) {
    echo $i.'<br>';
}
// Liefert A->Z
Geht nur leider nicht, da der Preprocessor den String-Wert natürlich nicht mit einem INT Wert vergleichen kann.

Hat jemand vielleicht einen Tipp bzw. damit schon mal zu tun gehabt?

Danke im Voraus & LG
Mike
 
Vielleicht solltest Du mit [phpf]chr[/phpf] arbeiten und 65 als Initialwert nehmen.

Gruß hpvw
 
Ergänzung:

Dafür eine eigene Funktion zu schreiben, die mir dann z.B.: für 30 den String 'AD' zurückliefert ist kein Problem.

Nur brauche ich dafür wieder eine Funktion, die mir den INT auf die Position im Alphabet mapped:

z.B.:
mapIntToAlphabet(5) -> 'E'
mapIntToAlphabet(1) -> 'A'
mapIntToAlphabet(10) -> 'J'
usw.
 
Ja, mit chr() habe ich mich schon beschäftigt.. ist aber nicht wirklich eine saubere Lösung...

Es geht dabei übrigens (wenn Du Dich errinerst) um die Sitzplatzgeschichte. Das können theoretisch unendlich viele Reihen bzw. Plätze sein.
 
Mit chr würde es funktionieren, verkompliziert die Sache aber um einiges...
Vor allem wenn es der Wert dann zB: 2000 ist...
Ansonsten könnte man mit dem ASCII Wertebereich 65-90 arbeiten (A-Z) und mittels modulo den rest berechnen (Division durch 26).

Aber ich befürchte mir ist zu heiß, um diese Funktion jetzt zu schreiben :)
Was solls, da muss ich wohl durch.
 
PHP:
//Finde ich ziemlich sauber:
$alpha=chr($intWert+64);
Werden die Zahlen größer, benötigst Du eine Funktion, hier mit Rekursion:
PHP:
<pre>
<?
function decToAlpha($int) {
    return ((floor($int/26)>0)
                ?decToAlpha(floor($int/26))
                :'')
            .chr($int%26+65);
}

$max=10000;
for ($i=1; $i < $max;$i++) {
    $z=$i-1;
    $a=decToAlpha($z);
    
    //Nur Formatierung:
    while (strlen($a)<5) {
        $a = 'A'.$a;
    }
    
    echo $a."\n";
}
?>
</pre>

Gruß hpvw
 
Hi!

Sind wahrscheinlich aufs selbe Ergebnis gekommen (hatte um 3.00 morgens eine Erleuchtung :)

Hier die Funktionen in beide Richtungen (sollte das mal wer brauchen):

PHP:
function convertAlphabetToInt($alpha_string) {
	$int_wert=0;
	$potenzcounter=0;
	for ($i=strlen($alpha_string);$i>0;$i--) {
		$ordinalwert=(ord(substr($alpha_string,$i-1,1))-64);
		$int_wert+=$ordinalwert*pow(26,$potenzcounter);
		$potenzcounter++;
	}
	return $int_wert;
}

function convertIntToAlphabet($int_wert) {
	if($int_wert%26>=1) {
		$alpha_string=chr(($int_wert%26)+64).$alpha_string;
		$alpha_string=convertIntToAlphabet($int_wert/26).$alpha_string;
	}
	return $alpha_string;
}

Danke & LG
Mike
 
KORREKTUR:

Die Funktion zum Umwandeln von Integerwerten in Ordinale Werte funktioniert im obigen Beispiel nicht (Da Z Modulo 26 == 0 [außerhalb des oridnalen Wertbereichs]). Korrekt sieht diese Funktion so aus:

PHP:
function convertIntToAlphabet($int_wert) {
		if($int_wert/26>1) {
			if($int_wert%26<>0) {
				$alpha_string=chr(floor(($int_wert%26)+64)).$alpha_string;
				$alpha_string=$this->convertIntToAlphabet(floor($int_wert/26)).$alpha_string;
			} else if ($int_wert%26<1) {
				$alpha_string='Z'.$alpha_string;
				$alpha_string=$this->convertIntToAlphabet(floor($int_wert/26)-1).$alpha_string;
			}
		} else {
			if($int_wert%26>0) {
				$alpha_string=chr(floor(($int_wert%26)+64)).$alpha_string;
			} else if($int_wert%26==0) {
				$alpha_string='Z'.$alpha_string;
			}
		}	
		return $alpha_string;
	}

Ich steh auf Rekursion :)

LG
Mike
 
Zuletzt bearbeitet:
Mik3e hat gesagt.:
KORREKTUR:

Die Funktion zum Umwandeln von Integerwerten in Ordinale Werte funktioniert im obigen Beispiel nicht (Da Z Modulo 26 == 0 [außerhalb des oridnalen Wertbereichs]). Korrekt sieht diese Funktion so aus:

PHP:
function convertIntToAlphabet($int_wert) {
		if($int_wert/26>1) {
			if($int_wert%26<>0) {
//... gekürzt fürs Zitat
		}	
		return $alpha_string;
	}
Ist mir ein bisschen zu lang, da bleibe ich lieber bei meiner Funktion ;) (Außer, Du weißt mir noch einen Fehler nach)

Mik3e hat gesagt.:
Ich steh auf Rekursion :)
Ich auch :D

Gruß hpvw
 
Aaaalso :)

1. Ist deine Funktion nicht unendlich
2. Ist sie mit der For-Schleife sicher bedeudent langsamer als eine rekursive Funktion wie meine :))

Außerdem haben wir beide folgendes Problem:

chr() müsste das alphabet folgendermaßen mappen:
A = 0
B = 1...
als chr()=chr()-1

DENN:
In Deinem Fall würde "Z" nicht funktionieren...
Da "Z" modulo 26 = 0 ergibt..
Und 0 ist kein ordinaler Wert...

Wenn man aber A=0, B=1 (also mit einem Zähler -1) beginnt, müßte es wieder passen (Weil Z dann 25/26 ist). Müsste ich aber noch versuchen).

LG
Mike
 

Neue Beiträge

Zurück