"von ... bis" - Zahlenabfolgen erkennen
Hey Leute,
kennt jemand von Euch vielleicht ein Script, welches aus einer
Zahlenabfolge ein "von ... bis" generieren kann?
Ein Beispiel:
1, 2, 3, 4, 5, 6 => 1-6
Einfach den ersten und letzten Testen geht natürlich nicht, denn:
1, 2, 3, 5, 6 ... das wäre 1-3, 5-6 (oder 5 & 6)
Eine Möglichkeit wäre natürlich zu gucken, ob der vorhergehende
Wert einen Zähler "drunter" liegt:
1 = Start
2 = 1 + 1 (also 1-2)
3 = 2 + 1 (also 1-3)
4 = 3 + 1 (also 1-4)
6 != 4 + 1 (also Bruch bei 1-4 und dann 6)
7 = 6 + 1 (also 6-7)
8 = 7 + 1 (also 6-8)
etc.
Was meint ihr dazu?
Grüße
Tobias
Re: "von ... bis" - Zahlenabfolgen erkennen
Tobias Wendorff <tobwenSPAM [at] gmx.de> wrote:
> kennt jemand von Euch vielleicht ein Script, welches aus einer
> Zahlenabfolge ein "von ... bis" generieren kann?
>
> Ein Beispiel:
> 1, 2, 3, 4, 5, 6 => 1-6
>
> Einfach den ersten und letzten Testen geht natürlich nicht, denn:
> 1, 2, 3, 5, 6 ... das wäre 1-3, 5-6 (oder 5 & 6)
Bei Perl's News::Newsrc (Die .newsrc-Dateien von Newsreader
benutzen ja diese Art von Zusammenfassungen.) wird das Modul
Set::IntSpan verwendet.
Entweder dort klauen, oder Daten via Perl-Script aufbereiten.
--
Web (en): http://www.no-spoon.de/ -*- Web (de): http://www.frell.de/
Re: "von ... bis" - Zahlenabfolgen erkennen
Hallo,
Tobias Wendorff schrieb:
> Hey Leute,
>
> kennt jemand von Euch vielleicht ein Script, welches aus einer
> Zahlenabfolge ein "von ... bis" generieren kann?
>
> Ein Beispiel:
> 1, 2, 3, 4, 5, 6 => 1-6
>
> Einfach den ersten und letzten Testen geht natürlich nicht, denn:
> 1, 2, 3, 5, 6 ... das wäre 1-3, 5-6 (oder 5 & 6)
Ist zwar ungetestet sollte aber stimmen.
function generateVonBis($folge)
{
$ret = array();
$i=$folge[0];
$von = $i;
$bis=0;
foreach ($folge as $zahl)
{
if($zahl!=$i)
{
array_push($ret,$von."-".$bis);
$i=$zahl;
$von=$i;
}
else
$i++;
$bis = $zahl;
}
return $ret;
}
mfg
Andreas
Re: "von ... bis" - Zahlenabfolgen erkennen
Andreas Eberhöfer schrieb:
> Hallo,
>
> Tobias Wendorff schrieb:
>> Hey Leute,
>>
>> kennt jemand von Euch vielleicht ein Script, welches aus einer
>> Zahlenabfolge ein "von ... bis" generieren kann?
>>
>> Ein Beispiel:
>> 1, 2, 3, 4, 5, 6 => 1-6
>>
>> Einfach den ersten und letzten Testen geht natürlich nicht, denn:
>> 1, 2, 3, 5, 6 ... das wäre 1-3, 5-6 (oder 5 & 6)
>
> Ist zwar ungetestet sollte aber stimmen.
>
> function generateVonBis($folge)
> {
> $ret = array();
> $i=$folge[0];
> $von = $i;
> $bis=0;
> foreach ($folge as $zahl)
> {
> if($zahl!=$i)
> {
> array_push($ret,$von."-".$bis);
> $i=$zahl;
> $von=$i;
> }
> else
> $i++;
> $bis = $zahl;
> }
> return $ret;
> }
Die Lösung stimmt nicht ;)
Nimmt man (1,2,3,5,6,9,11,12)
erhält man die Lösung:
Array
(
[0] => 1-3
[1] => 5-5
[2] => 6-6
[3] => 9-9
[4] => 11-11
)
Gruß,
Torsten
Re: "von ... bis" - Zahlenabfolgen erkennen
Tobias Wendorff schrieb:
> Hey Leute,
>
> kennt jemand von Euch vielleicht ein Script, welches aus einer
> Zahlenabfolge ein "von ... bis" generieren kann?
>
> Ein Beispiel:
> 1, 2, 3, 4, 5, 6 => 1-6
function vonbis($zahlenfolge)
{
sort($zahlenfolge);
$von = $zahlenfolge[0];
$bis = end($zahlenfolge);
$vonbis = $von . '-' . $bis;
return $vonbis;
}
Gruss
Christoph
Re: "von ... bis" - Zahlenabfolgen erkennen
Am Tue, 21 Aug 2007 17:30:06 +0200 schrieb Christoph Schmidt:
> Tobias Wendorff schrieb:
>> Hey Leute,
>>
>> kennt jemand von Euch vielleicht ein Script, welches aus einer
>> Zahlenabfolge ein "von ... bis" generieren kann?
>>
>> Ein Beispiel:
>> 1, 2, 3, 4, 5, 6 => 1-6
>
> function vonbis($zahlenfolge)
> {
> sort($zahlenfolge);
> $von = $zahlenfolge[0];
> $bis = end($zahlenfolge);
> $vonbis = $von . '-' . $bis;
>
> return $vonbis;
> }
Diese Lösung wurde doch vom OP bereits ausgeschlossen (in dem Artikel auf
den Du geantwortet hast) weil dann Zahlenreihen mit Lücken fehlerhaft
erkannt würden. Deine Funtion würde aus 1,2,3,4,125 als Resultat liefern
1-125 und das ist man schlichtweg falsch...
MfG
Norbert
Re: "von ... bis" - Zahlenabfolgen erkennen
Torsten Zühlsdorff schrieb:
> Die Lösung stimmt nicht ;)
>
> Nimmt man (1,2,3,5,6,9,11,12)
> erhält man die Lösung:
> Array
> (
> [0] => 1-3
> [1] => 5-5
> [2] => 6-6
> [3] => 9-9
> [4] => 11-11
> )
>
Ok hast Recht. Ich hab nochmal nachgebessert:
function generateVonBis($folge)
{
$ret = array();
$current=$folge[0];
$von = $current;
$bis=0;
for($i=0;$i<sizeof($folge);$i++)
{
$zahl = $folge[$i];
if($zahl!=$current)
{
array_push($ret,$von."-".$bis);
$current=$zahl;
$von=$current;
}
//Damit die letze Zahl nicht verloren geht
if($i==sizeof($folge)-1)
{
array_push($ret,$von."-".($bis+1));
}
//Das Hochzählen muss immer passieren nicht nur im else Fall
$current++;
$bis = $zahl;
}
return $ret;
}
Re: "von ... bis" - Zahlenabfolgen erkennen
Hallo, Tobias,
Du (tobwenSPAM) meintest am 21.08.07:
> Ein Beispiel:
> 1, 2, 3, 4, 5, 6 => 1-6
> Einfach den ersten und letzten Testen geht natürlich nicht, denn:
> 1, 2, 3, 5, 6 ... das wäre 1-3, 5-6 (oder 5 & 6)
Vielleicht biete ich nur einen Umweg an - bei Linux gibt es das Programm
"comm", das bei 2 (sortierten) Dateien die Unterschiede und
Gemeinsamkeiten auflistet.
Aus
1
2
3
5
6
9
11
12
macht es
1
2
3
5
6
9
11
12
markiert also die Lücken. Damit muss nicht mehr numerisch kontrolliert
werden, sondern "auf Lücke".
Viele Gruesse!
Helmut
Re: "von ... bis" - Zahlenabfolgen erkennen
Fast ... ergibt:
Array
(
[0] => 1-3
[1] => 5-6
[2] => 9-9
[3] => 11-12
)
Andreas Eberhöfer wrote:
> Torsten Zühlsdorff schrieb:
>> Die Lösung stimmt nicht ;)
>>
>> Nimmt man (1,2,3,5,6,9,11,12)
>> erhält man die Lösung:
>> Array
>> (
>> [0] => 1-3
>> [1] => 5-5
>> [2] => 6-6
>> [3] => 9-9
>> [4] => 11-11
>> )
>>
>
> Ok hast Recht. Ich hab nochmal nachgebessert:
>
> function generateVonBis($folge)
> {
> $ret = array();
> $current=$folge[0];
> $von = $current;
> $bis=0;
> for($i=0;$i<sizeof($folge);$i++)
> {
> $zahl = $folge[$i];
>
> if($zahl!=$current)
> {
> array_push($ret,$von."-".$bis);
> $current=$zahl;
> $von=$current;
> }
>
> //Damit die letze Zahl nicht verloren geht
> if($i==sizeof($folge)-1)
> {
> array_push($ret,$von."-".($bis+1));
> }
>
> //Das Hochzählen muss immer passieren nicht nur im else Fall
> $current++;
> $bis = $zahl;
> }
>
> return $ret;
> }
Re: "von ... bis" - Zahlenabfolgen erkennen
Tobias Wendorff schrieb:
> Fast ... ergibt:
>
> Array
> (
> [0] => 1-3
> [1] => 5-6
> [2] => 9-9
> [3] => 11-12
> )
Zuerst TOFU (Text oben Fullquote unten) ist schlecht siehe
(http://learn.to/quote).
Was stört dich noch? Das 9-9? Ok ist nicht schön, aber leicht zu ändern.
if($zahl!=$current)
{
if($von==$bis)
array_push($ret,$von);
else
array_push($ret,$von."-".$bis);
$current=$zahl;
$von=$current;
}
Diese zusätzlich Überprüfung musst du dann auch den if-Block für die
letze Zahl einbauen.
mfg
Andreas
Re: "von ... bis" - Zahlenabfolgen erkennen // meine Variante
Das hier wäre meine Variante:
function Erkennung_vonbis($folge) {
$abfolge_temp = '';
foreach($folge as $index => $zahl_aktuell) {
if ($index != 0) {
$zahl_vorher = $zahl_aktuell-1;
$zahl_vorher_array = $folge[$index-1];
if ($zahl_vorher_array != $zahl_vorher) {
if ($abfolge_temp !== $folge[$index-1]) {
$abfolge_temp .= ' - ' . $folge[$index-1];
}
$output[] = $abfolge_temp;
$abfolge_temp = $zahl_aktuell;
}
} else {
$abfolge_temp = $zahl_aktuell;
}
}
if ($abfolge_temp !== $zahl_aktuell) {
$abfolge_temp .= ' - ' . $folge[$index];
} else {
$abfolge_temp = $zahl_aktuell;
}
$output[] = $abfolge_temp;
return $output;
}
Grüße
Tobias
Re: "von ... bis" - Zahlenabfolgen erkennen
Andreas Eberhöfer wrote:
> Zuerst TOFU (Text oben Fullquote unten) ist schlecht siehe
> (http://learn.to/quote).
sorry
> Was stört dich noch? Das 9-9? Ok ist nicht schön, aber leicht zu
> ändern.
>
> if($zahl!=$current)
> {
> if($von==$bis)
> array_push($ret,$von);
> else
> array_push($ret,$von."-".$bis);
>
> $current=$zahl;
> $von=$current;
> }
>
> Diese zusätzlich Überprüfung musst du dann auch den if-Block für die
> letze Zahl einbauen.
Okay, funktioniert. Aber dabei ist mir noch ein anderes Problem
aufgefallen:
(1,2,3,5,6,9,11,12,10) ergibt:
Array
(
[0] => 1-3
[1] => 5-6
[2] => 9-9
[3] => 11-12
[4] => 10-13
)
Huch, wo bekommt er denn die 13 her? :-))
Re: "von ... bis" - Zahlenabfolgen erkennen
$arr = array(1,2,3,5,6,8,9);
$von = $arr[0];
$bis = $von-1;
foreach($arr as $item)
{
if($bis<$item-1)
{
echo "$von-$bis\n";
$von = $item;
}
$bis = $item;
}
echo "$von-$bis\n";
Peter
Re: "von ... bis" - Zahlenabfolgen erkennen
Hallo Peter,
Peter Schleif wrote:
> $arr = array(1,2,3,5,6,8,9);
> $von = $arr[0];
> $bis = $von-1;
>
> foreach($arr as $item)
> {
> if($bis<$item-1)
> {
> echo "$von-$bis\n";
> $von = $item;
> }
> $bis = $item;
> }
> echo "$von-$bis\n";
(2,1,2,3,5,8,9,13) => nur "2-3" wird ausgegeben, nicht "2,1-3"
Re: "von ... bis" - Zahlenabfolgen erkennen
Tobias Wendorff schrieb:
>
> (2,1,2,3,5,8,9,13) => nur "2-3" wird ausgegeben, nicht "2,1-3"
Aufsteigende Zahlenfolge!
INHO war bisher von nichts anderem zu lesen.
Re: "von ... bis" - Zahlenabfolgen erkennen
Peter Schleif wrote:
> Tobias Wendorff schrieb:
>>
>> (2,1,2,3,5,8,9,13) => nur "2-3" wird ausgegeben, nicht "2,1-3"
>
> Aufsteigende Zahlenfolge!
>
> INHO war bisher von nichts anderem zu lesen.
Ja, aber 1,2,3 ist doch aufsteigend :-)
Re: "von ... bis" - Zahlenabfolgen erkennen // Nachtrag
Tobias Wendorff wrote:
> Huch, wo bekommt er denn die 13 her? :-))
Okay ... meine Frage war ja nach aufsteigenden Zahlenfolgen.
Sorry, hätte das in die Startbedingungen setzen sollen.
Danke aber für die Hilfe!
Re: "von ... bis" - Zahlenabfolgen erkennen
Am Tue, 21 Aug 2007 19:46:38 +0200 schrieb Tobias Wendorff:
> Peter Schleif wrote:
>> Tobias Wendorff schrieb:
>>>
>>> (2,1,2,3,5,8,9,13) => nur "2-3" wird ausgegeben, nicht "2,1-3"
>>
>> Aufsteigende Zahlenfolge!
>>
>> INHO war bisher von nichts anderem zu lesen.
>
> Ja, aber 1,2,3 ist doch aufsteigend :-)
Aber nicht 2,1,2,3...
Re: "von ... bis" - Zahlenabfolgen erkennen // Nachtrag
Tobias Wendorff schrieb:
>Sorry, hätte das in die Startbedingungen setzen sollen.
Dann halt noch ein sort an den Anfang und gut ist.
--
Wolfgang Fellger
Re: "von ... bis" - Zahlenabfolgen erkennen // noch eine Variante
Hier noch eine Möglichkeit:
function VonBis_v2($folge) {
foreach($folge as $zahl_aktuell) {
if(!isset($zahl_vorher)) {
$zahl_vorher = $zahl_aktuell;
} elseif(!isset($zahl_nachher) && ($zahl_aktuell - $zahl_vorher) == 1) {
$zahl_nachher = $zahl_aktuell;
} elseif(!isset($zahl_nachher) && ($zahl_aktuell - $zahl_vorher) != 1) {
$output[] = $zahl_vorher;
$zahl_vorher = $zahl_aktuell;
} elseif(($zahl_aktuell - $zahl_nachher) == 1) {
$zahl_nachher = $zahl_aktuell;
} elseif(($zahl_aktuell - $zahl_nachher) != 1) {
$output[] = $zahl_vorher . ' - '. $zahl_nachher;
$zahl_vorher = $zahl_aktuell;
unset($zahl_nachher);
}
}
$output[] = isset($zahl_vorher) ? ($zahl_vorher . (isset($zahl_nachher) ? ' - ' . $zahl_nachher : '')) : '';
return $output;
}
Re: "von ... bis" - Zahlenabfolgen erkennen
Norbert Melzer wrote:
>> Ja, aber 1,2,3 ist doch aufsteigend :-)
>
> Aber nicht 2,1,2,3...
Ja, in der Tat mein Fehler. Hätte auf diese Möglichkeiten
hinweisen sollen. Habe es in meinen beiden Methoden beachtet.
Danke für die Hilfe.
Re: "von ... bis" - Zahlenabfolgen erkennen
On 21 Aug., 19:46, "Tobias Wendorff" <tobwenS... [at] gmx.de> wrote:
>
> >> (2,1,2,3,5,8,9,13) => nur "2-3" wird ausgegeben, nicht "2,1-3"
> Ja, aber 1,2,3 ist doch aufsteigend :-)
<?php
$arr = array(2,1,2,3,5,8,9,13);
$von = $arr[0];
$bis = $von-1;
foreach($arr as $item)
{
if($bis<$item-1 || $bis>$item)
{
echo $von.($von==$bis ? "" : "-$bis")."\n";
$von = $item;
}
$bis = $item;
}
echo $von.($von==$bis ? "" : "-$bis")."\n";
?>
Peter
Re: "von ... bis" - Zahlenabfolgen erkennen
Tobias Wendorff schrieb:
> Hey Leute,
>
> kennt jemand von Euch vielleicht ein Script, welches aus einer
> Zahlenabfolge ein "von ... bis" generieren kann?
Ich will auch:
<?php
$arr = array(2,2,2,1,2,2,3,7,6,5,1,2,3,5,6,8,9,10,11,12,13,5);
for ($i=1,$result[$j=0] = ($von = $arr[0]); $i<count($arr); $i++)
if ($arr[$i] == $arr[$i-1]+1) $result[$j] = "$von-$arr[$i]";
else $result[++$j] = ($von = $arr[$i]);
print_r ($result);
?>
Zahlenabfolgen kann man am Datentyp String erkennen, einzelne Zahlen haben
den Datentyp Integer.
viele grüße
ralph
Re: "von ... bis" - Zahlenabfolgen erkennen
Tobias Wendorff wrote:
> Hey Leute,
>
> kennt jemand von Euch vielleicht ein Script, welches aus einer
> Zahlenabfolge ein "von ... bis" generieren kann?
>
> Ein Beispiel:
> 1, 2, 3, 4, 5, 6 => 1-6
>
> Einfach den ersten und letzten Testen geht natürlich nicht, denn:
> 1, 2, 3, 5, 6 ... das wäre 1-3, 5-6 (oder 5 & 6)
>
> Eine Möglichkeit wäre natürlich zu gucken, ob der vorhergehende
> Wert einen Zähler "drunter" liegt:
>
> 1 = Start
> 2 = 1 + 1 (also 1-2)
> 3 = 2 + 1 (also 1-3)
> 4 = 3 + 1 (also 1-4)
> 6 != 4 + 1 (also Bruch bei 1-4 und dann 6)
> 7 = 6 + 1 (also 6-7)
> 8 = 7 + 1 (also 6-8)
> etc.
>
> Was meint ihr dazu?
>
> Grüße
> Tobias
>
Meine Version:
<code>
function get_numerical_series($v)
{
sort($v, SORT_NUMERIC);
$r = array();
$t = null;
foreach ($v as $n)
{
//erstes Element
if (is_null($t))
{
$t = array($n);
}
else
{
//letztes Element +1 ist gleich aktuelles Element
if (($t[count($t) - 1] + 1) == $n)
{
//Element zur aktuellen Reihe hinzufügen
$t[] = $n;
}
else
{
//Wenn aktuelle Reihe 2 oder mehr Element enthält in das
Return-Array speichern
if (count($t) >= 2)
{
$r[] = $t[0] . "-" . $t[count($t)-1];
}
//Aktuelle Reihe zurücksetzen
$t = array($n);
}
}
}
if (count($t) >= 2)
{
$r[] = $t[0] . "-" . $t[count($t)-1];
}
return $r;
}
$numbers = array(1,3,4,5,7,9,11,12,10,37,59,60,64,27,99,98,97);
print_r(get_numerical_series($numbers));
</code>
Ausgabe:
Array
(
[0] => 3-5
[1] => 9-12
[2] => 59-60
[3] => 97-99
)
Einschränkungen:
-Zahlen dürfen im Array nicht mehrfach vorkommen
Joe
Re: "von ... bis" - Zahlenabfolgen erkennen
Stefan Scholl wrote:
> Bei Perl's News::Newsrc (Die .newsrc-Dateien von Newsreader
> benutzen ja diese Art von Zusammenfassungen.) wird das Modul
> Set::IntSpan verwendet.
Apropos Perl:
...
my $text = '2,2,2,1,2,2,3,7,6,5,1,2,3,5,6,8,9,10,11,12,13,5';
my ( [at] num, $lc);
() = $text =~ /(\d+)(?{$lc+=!!($num[$lc][-1]+1-$1);push [at] {$num[$lc]},$1})/g;
...
Ausdrucken mit:
print map " [at] $_\n", [at] num;
;)
Viele Grüße
M.
Re: "von ... bis" - Zahlenabfolgen erkennen
Mirco Wahab wrote:
> Ausdrucken mit:
>
> print map " [at] $_\n", [at] num;
Ach so, der Korrekte Ausdruck erfordert eine kleine
Änderung, z.B.:
...
my ( [at] num, $lc);
() = '2,2,2,1,2,2,3,7,6,5,1,2,3,5,6,8,9,10,11,12,13,5'
=~ /(\d+)(?{$lc+=!!($num[$lc][-1]+1-$1);push [at] {$num[$lc]},$1})/g;
print map $_->[0].($#$_?"-$_->[-1]":'')."\n", [at] num;
...
Das ergibt:
2
2
2
1-2
2-3
7
6
5
1-3
5-6
8-13
5
(werds jetzt auch mal in PHP versuchen!)
Viele Grüße
M.
Re: "von ... bis" - Zahlenabfolgen erkennen
Tobias Wendorff schrieb:
> kennt jemand von Euch vielleicht ein Script, welches aus einer
> Zahlenabfolge ein "von ... bis" generieren kann?
>
> Ein Beispiel:
> 1, 2, 3, 4, 5, 6 => 1-6
>
> Einfach den ersten und letzten Testen geht natürlich nicht, denn:
> 1, 2, 3, 5, 6 ... das wäre 1-3, 5-6 (oder 5 & 6)
Das war vor kurzem eine Programmieraufgabe von codegolf.com, nämlich
"Home On The Range" (<http://codegolf.com/home-on-the-range>). Der
kürzeste PHP-Beitrag hat 94 Zeichen, meine Perl-Lösung hat 56 und
verwendet einige Spezialitäten, die PHP nicht hat. Auf Anfrage kann ich
sie Dir zuschicken. Ich glaube nicht, dass Dir das direkt weiterhilft,
aber wenn Du generell auf kompakten Code stehst, könntest Du einen
ansprechen, der eine PHP-Abgabe gemacht hat - mit hoher
Wahrscheinlichkeit findest Du solche Leute im Forum dazu
(<http://codegolf.com/boards/board/view/13>) oder im IRC-Channel.
Mirko
--
Schmeddingstrasse 123 g, 48149 Muenster, <http://mirko.westermeier.de/>
E-Mail: <mirko [at] westermeier.de>, OpenPGP-Key-ID: 0x730E195D
Key fingerprint: 55A8 9646 9B58 60AC B5BC 9661 FDD4 93C0 730E 195D
E-Mails von mir sind signiert. Unsignierte E-Mails sind nicht von mir.
Re: "von ... bis" - Zahlenabfolgen erkennen
Mirko Westermeier wrote:
> Das war vor kurzem eine Programmieraufgabe von codegolf.com, nämlich
> "Home On The Range" (<http://codegolf.com/home-on-the-range>). Der
> kürzeste PHP-Beitrag hat 94 Zeichen, meine Perl-Lösung hat 56 und
> verwendet einige Spezialitäten, die PHP nicht hat. Auf Anfrage kann
> ich sie Dir zuschicken. Ich glaube nicht, dass Dir das direkt
> weiterhilft, aber wenn Du generell auf kompakten Code stehst,
> könntest Du einen ansprechen, der eine PHP-Abgabe gemacht hat - mit
> hoher Wahrscheinlichkeit findest Du solche Leute im Forum dazu
> (<http://codegolf.com/boards/board/view/13>) oder im IRC-Channel.
Gerne, aber das Problem ist: Ich bekomme Perl nicht unter PHP
in win32 zum Laufen. Die DLL für Perl ist outdated und PHP schmeißt
immer einen Error raus (php -v).