字符数组处理超大数运算_数组处理功能

字符数组处理超大数运算

In my previous article on PHP arrays I suggested a number of things that are tables and therefore can also be expressed as arrays. In this article I’ll use a pack of playing cards to explore some of the built-in array functions most often needed by PHP programmers.

在我以前关于PHP数组的文章中,我建议了许多东西,它们都是表,因此也可以表示为数组。 在本文中,我将使用一副扑克牌探索PHP程序员最常需要的一些内置数组函数。

To highlight some of the array-handling functions PHP offers, I’ll be using some components of Buraco – a game very popular in my part of the world and quite similar to Rummy. Real-world Buraco is played with two decks (104 cards) plus two Joker cards. It also has a stock pile that holds all cards not dealt to the players, but I won’t use them here so you needn’t worry about them.

为了强调PHP提供的一些数组处理功能,我将使用Buraco的某些组件– Buraco这个游戏在我的世界中非常流行,与Rummy非常相似。 现实世界中的Buraco用两副牌(104张卡)和两张Joker卡来玩。 它也有一个库存堆,存放所有未发给玩家的卡,但是我在这里不使用它们,因此您不必担心它们。

代表一副纸牌 (Representing a Deck of Cards)

Cards date back possibly to the ninth century, the time when sheets of paper first began to be used in China. They followed the path of other inventions from the East – first to the Arab world from where they were then taken to Europe and later into the New World. In its current most popular form, the French Pack, a deck of playing cards has 52 cards divided in four suits, clubs (♣), diamonds (♦), hearts (♥) and spades (♠). Each suit has 13 cards, or faces: A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q and K.

卡片的历史可以追溯到9世纪,那时候中国才开始使用纸张。 他们沿着东方的其他发明之路走-首先是阿拉伯世界,然后从那里被带到欧洲,然后又进入新世界。 在目前最受欢迎的形式“法国组合”中,一副扑克牌有52张牌,分为四套西装,球杆(♣),钻石(♦),心形(♥)和黑桃(♠)。 每套西装都有13张卡片或面Kong:A,2、3、4、5、6、7、8、9、10,J,Q和K。

You can write arrays to hold both suits and faces like this:

您可以编写数组来容纳西装和面Kong,如下所示:

<?php
$suits = array ("clubs", "diamonds", "hearts", "spades");
$faces = array (1 => "A", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13");

Both are numerically indexed arrays – that is, they have integer-based keys. Because I didn’t explicitly give any keys when I defined $suits, PHP automatically assigns keys to them starting with 0. So, the value of $suits[0] is “clubs” and $suits[3] is “spades”. I did however provide a key to the first element of $faces. PHP assigns each new key by taking the the maximum integer index and adding 1 to it. $faces[1] is “A”, $faces[2] is “02”, $faces[3] is “03” and so on. You’ll notice I forced PHP to start indexing $faces with 1 so the numerical card faces are identical to their respective keys.

两者都是数字索引数组–也就是说,它们都有基于整数的键。 因为在定义$suits时我没有明确给出任何键,所以PHP会自动从0开始为它们分配键。因此, $suits[0]值为“ clubs”, $suits[3]值为“ spades”。 但是,我确实提供了$ faces第一个元素的关键。 PHP通过采用最大整数索引并为其添加1来分配每个新键。 $faces[1]是“ A”, $faces[2]是“ 02”, $faces[3]是“ 03”,依此类推。 您会注意到,我强迫PHP开始用1索引$faces ,以便数字卡的面与其各自的键相同。

You can use two foreach loop to create a master array of all 52 cards, each represented as a string in the format face|suit, like this:

您可以使用两个foreach循环来创建所有52张卡的主阵列,每张卡均以face | suit格式表示为字符串,如下所示:

<?php
$deck = array();
foreach ($suits as $suit) {
    foreach ($faces as $face) {
        $deck[] = $face . "|" . $suit;
    }
}

The result of the above code is the same as if you had populated $deck by hand:

以上代码的结果与您手动填充$deck的结果相同:

<?php
$deck = array("A|clubs", "02|clubs", "03|clubs", "04|clubs", ... "Q|spades", "K|spades");

Some of the more experienced readers may be asking why not use a nested array as opposed to strings, such as:

一些更有经验的读者可能会问,为什么不使用嵌套数组而不是字符串,例如:

<?php
$deck = array();
$deck["A"] = array("clubs", "diamonds", "hearts", "spades");
$deck["02"] = array("clubs", "diamonds", "hearts", "spades");
$deck["03"] = array("clubs", "diamonds", "hearts", "spades");
...

Well, that’s the beauty of it: strings can sometimes be treated as non-associative, single level arrays but arrays nonetheless! In fact, the same function used to count the number of elements in an array – count() – can also be used to count the number of characters in a string! Later you’ll see how to convert strings into arrays.

好吧,这就是它的美:字符串有时可以被视为非关联的单级数组,但是仍然可以将数组视为! 实际上,用于计数数组中元素数量的同一函数– count() –也可以用于计算字符串中字符的数量! 稍后,您将看到如何将字符串转换为数组。

发牌 (Dealing a Hand)

Let’s begin by shuffling the deck and dealing out a hand of 11 random cards. To do this, you can use the function array_rand(). It returns an array of keys taken randomly from the original. The function was designed to return keys rather than values so it can work just as efficiently with nested arrays as with single-level arrays, and you can always obtain the values if you know the key.

让我们从改组游戏开始并分发11张随机卡开始。 为此,您可以使用array_rand()函数。 它返回从原始数组中随机抽取的一组键。 该函数旨在返回而不是值,因此它可以与嵌套数组和单级数组一样高效地工作,并且只要知道键就可以始终获取值。

<?php
$myKeys = array_rand($deck, 11);
$myHand = array();
foreach ($myKeys as $key) {
    $myHand[] = $deck[$key];
    unset($deck[$key]);
}

Initially, the temporary $myKeys array is created whose values are 11 random keys found in $deck. Then a foreach loop uses the value of $myKeys to get the corresponding value from $deck into $myHand. Of course this does not remove elements from the original deck. If you were to call array_rand() again, it is entirely possible you could get a few keys indexing again some cards that had already been drawn! To make sure this doesn’t happen, unset() is called to delete the element from $deck to make sure it can’t be reused.

最初,创建临时$myKeys数组,其值是$deck中的11个随机键。 然后, foreach循环使用$myKeys的值将相应的值从$deck$myHand 。 当然,这不会从原始卡座中删除元素。 如果要再次调用array_rand() ,则完全有可能再次获得一些索引一些已绘制卡的索引! 为了确保不会发生这种情况,调用unset()$deck删除该元素以确保它不能被重用。

To find out whether a card, say “06|hearts” (6♥), is in the hand that was dealt, you can use the in_array() function. It accepts a needle first, the desired value to search for, and then the haystack, the array in which to search.

要确定发出的牌中是否有卡片,说“ 06 | hearts”(6♥),可以使用in_array()函数。 它首先接受一根 ,即要搜索的所需值,然后接受要在其中搜索数组的干草堆

<?php
if (in_array("06|hearts", $myHand)) {
    echo "I found it!";
}

As a side note about needles and haystacks, evangelists of other languages love to find faults with PHP (and of course the reverse is also true!). The only criticism I could never refute was PHP’s irritating inconsistent parameter order between similar functions. Some functions, like in_array(), accept the needle first, while other functions accept the haystack first. I know long-time PHP developers who still have trouble remembering which order some functions use, so don’t be too put off if you find yourself always needing to check the online documentation.

作为针线和干草堆的一个补充说明,其他语言的传播者都喜欢发现PHP的错误(当然,反之亦然!)。 我永远无法反驳的唯一批评是PHP的相似函数之间令人讨厌的参数顺序不一致。 一些函数(例如in_array()首先接受针,而其他函数则首先接受干草堆。 我知道长期使用PHP的开发人员仍然很难记住某些功能使用的顺序,因此,如果您发现自己始终需要检查在线文档,也不要太拖延。

in_array() returns only whether something was found in an array, not the key of the value. Most of the time this is sufficient. But if you need to know the key as well, consider using array_search().

in_array()仅返回是否在数组中找到内容,而不返回值的键。 在大多数情况下,这已足够。 但是,如果您还需要知道密钥,请考虑使用array_search()

Good housekeeping is important, and thanks to the face|suit manner in which the cards are represented, sorting them is as easy as using sort(). This function orders the elements of the array in ascending alphabetical and numeric order:

良好的内务管理是非常重要的,并且由于面部|西装以何种方式卡为代表,它们排序是那么容易,因为使用sort() 此函数以字母和数字的升序对数组的元素进行排序:

<?php
sort($myHand);

The sort() function is peculiar in that it operates on its own argument! If you wanted to preserve the original order of $myHand you would have to copy it to another variable before sorting:

sort()函数的独特之处在于它对自己的参数进行操作! 如果要保留$myHand的原始顺序,则必须在排序之前将其复制到另一个变量:

<?php
$preservedHand = $myHand;
sort($myHand);

融化和丢弃 (Melds and Discards)

Buraco, like rummy, is a game of runs – sequences laid down on the table. The act of removing cards from the hand onto a run is called melding. For example, cards 9♦, 10♦, J♦ and Q♦ if they were in $myHand could be melded to make a run. Programatically this means removing the cards from $myHand and putting them into a new array, $myRuns. You can use the function array_slice() which returns a copy of a range of elements from an array, very much like the way substr() works on strings. Assuming the sequences occupies positions 0 through 3 in $myHand:

就像拉米纸牌游戏一样,Buraco是一场奔跑的游戏-摆在桌子上的顺序。 将卡从手上移到奔跑的行为被称为融合 。 例如,如果卡片9♦,10♦,J♦和Q♦在$myHand可以将其融合以进行奔跑。 以编程方式,这意味着从$myHand删除卡并将它们放入新数组$myRuns 。 您可以使用函数array_slice()从数组中返回一系列元素的副本,这与substr()在字符串上的工作方式非常相似。 假设序列在$myHand占据位置0到3:

<?php
$myRuns = array();
$myRuns[] = array_slice ($myHand, 0, 4);
$myHand = array_slice($myHand, 5, 7);

The first line creates the array $myRuns and the second one adds to it a sub-array composed of 4 elements from $myHand beginning at index 0, which is the first position in the array. array_slice() does not delete the slice from the original array, which is a problem here since you need to remove the cards from your hand that you meld or discard. The solution here is to use array_slice() a second time to reassign the other elements of $myHand to itself.

第一行创建数组$myRuns ,第二行$myRuns添加一个子数组,该子数组由$myHand的4个元素组成,从索引0开始,这是数组中的第一个位置。 array_slice()不会从原始数组中删除切片,这在这里是一个问题,因为您需要从手中取出要融合或丢弃的卡片。 这里的解决方案是第二次使用array_slice()$myHand的其他元素重新分配给它自己。

At the beginning of his turn, a player must either pick up one card from the stock or all cards from the discard pile and add them to his hand. Both options can be done using the array_merge() function. The function returns an array composed of all the elements from the given arrays in the order they were provided. For example, let’s say the state of the game looks like this:

在回合开始时,玩家必须从股票中拾取一张牌,或从弃牌堆中拾取所有牌并将其添加到他的手上。 这两个选项都可以使用array_merge()函数完成。 该函数返回一个数组,该数组由给定数组中所有元素的提供顺序组成。 例如,假设游戏状态如下:

Player’s Hand: 2♣, 5♥, 6♠, 6♥, 7♦, 8♥, K♠Run: 9♦, 10♦, J♦, Q♦Discard Pile: 7♠, J♠, 4♥, 4♦

玩家手牌: 2♣,5♥,6♠,6♥,7♦,8♥,K♠ 跑: 9♦,10♦,J♦,Q♦ 弃牌: 7♠,J♠,4♥,4♦

To pick up all the cards in the discard pile and add them to the players hand, you could write:

要拾起弃牌堆中的所有卡并将它们添加到玩家手中,您可以编写:

<?php
$myHand = array_merge($myHand, $discarded);

Afterwards, $myHand would contain:

之后, $myHand将包含:

array("02|clubs", "5|hearts", "06|spades", "06|hearts", "07|diamonds", "08|hearts", "13|spades", "07|spades", "11|spades", "04|hearts", "04|diamonds")

伸出手 (Showing the Hand)

It’d be nice to display one or more cards in the browser. My strategy is to use the face|suit notation to create a number of HTML image tags that will show face and suit graphics. While it is not likely an effective solution for a real-world application, it does afford me an opportunity to show you one last function, explode().

最好在浏览器中显示一张或多张卡片。 我的策略是使用西装符号创建许多HTML图像标签,这些标签将显示面部和西装图形。 尽管对于实际应用程序可能不是有效的解决方案,但它确实为我提供了向您展示最后一个函数explode()

<?php
foreach ($myHand as $card) {
    $tmpArray = explode("|", $card);
    echo '<img src="img/face_' . $faces[$tmpArray[0]] . '.png">";
    echo '<img src="img/suit_' . $suits[$tmpArray[1]] . '.png">";
    echo "&nbsp;"; // Just a blank space for visual separation 
}

The foreach loops through all of the cards in $myHand and returns one face|suit value each iteration as $card. The explode() function takes each $card value and splits it into two pieces using the vertical bar as the separator. It then returns an array with as many elements as there are parts. I’m using a vertical bar here, but explode() will work with any character or sequence of characters.

foreach循环遍历$myHand所有卡,并在每次迭代中将一个face |值作为$cardexplode()函数获取每个$card值,并使用竖线作为分隔符将其分为两部分。 然后,它返回一个数组,该数组具有与部分一样多的元素。 我在这里使用竖线,但是explode()可以使用任何字符或字符序列。

摘要 (Summary)

PHP has over 70 array-related functions. In this tutorial you’ve seen how to use a mere handful of them to perform some basic array manipulations. These functions are tools you’ll use often to solve programming problem or, as I prefer to call them, challenges. It’s important to develop a familiarity with them so that when you plan your script you can make sound decisions based on the results you need.

PHP具有70多个与数组相关的功能。 在本教程中,您已经了解了如何使用其中的少数几个执行一些基本的数组操作。 这些功能是您经常用于解决编程问题或挑战(我更喜欢称之为挑战)的工具。 重要的是要熟悉它们,以便在计划脚本时可以根据所需结果做出合理的决定。

Image via Cindy Haggerty / Shutterstock

图片来自辛迪·哈格蒂 ( Cindy Haggerty) / Shutterstock

翻译自: https://www.sitepoint.com/array-handling-functions/

字符数组处理超大数运算

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值