Çox çox ifadələr varsa?

Aşağıdakı kod həqiqətən mənə lazım olan şəkildə işləyir, lakin çirkin, həddindən artıq və ya bir çox başqa şeylərdir. Mən formullara baxdım və bir neçə həlli yazmağa çalışdım, amma sonunda eyni sayda ifadələr aldım.

Bu halda mənə fayda gətirəcək riyazi formulun bir növü varmı, yoxsa ifadələr 16 etibarlıdır?

Kodu izah etmək üçün, eyni zamanda posat ilə oyunun müxtəlifliyinə aiddir. İki oyunçunun hər biri dörd hərəkət düyməsini var və nəticələr bir sıra (0-3) gəlir, ancaq kömək edərsə "bir" və "iki" dəyişənlər bir şeyə təyin edilə bilər. Nəticə: 0 = heç bir qalibiyyət, 1 = p1 qalibiyyət, 2 = p2 qalibiyyət, 3 = ikisi də qazanacaq.

 public int fightMath(int one, int two) { if(one == 0  two == 0) { result = 0; } else if(one == 0  two == 1) { result = 0; } else if(one == 0  two == 2) { result = 1; } else if(one == 0  two == 3) { result = 2; } else if(one == 1  two == 0) { result = 0; } else if(one == 1  two == 1) { result = 0; } else if(one == 1  two == 2) { result = 2; } else if(one == 1  two == 3) { result = 1; } else if(one == 2  two == 0) { result = 2; } else if(one == 2  two == 1) { result = 1; } else if(one == 2  two == 2) { result = 3; } else if(one == 2  two == 3) { result = 3; } else if(one == 3  two == 0) { result = 1; } else if(one == 3  two == 1) { result = 2; } else if(one == 3  two == 2) { result = 3; } else if(one == 3  two == 3) { result = 3; } return result; } 
256
19 марта '14 в 12:24 2014-03-19 12:24 TomFirth 19: 14 'də saat 12: 24-də təyin olunub
@ 26 cavab

Bir formulla gəlmək mümkün deyilsə, belə bir məhdud sayda nəticə üçün bir masa istifadə edə bilərsiniz:

 final int[][] result = new int[][] { { 0, 0, 1, 2 }, { 0, 0, 2, 1 }, { 2, 1, 3, 3 }, { 1, 2, 3, 3 } }; return result[one][two]; 
589
19 марта '14 в 12:32 2014-03-19 12:32 Cavab 19 mart 2014- il saat 12: 32-də verilir. 2014-03-19 12:32

Sizin məlumatlarınız çox kiçik olduğundan, hər şeyi uzun bir tamsayıya yığaraq bir formulata çevirə bilərsiniz

 public int fightMath(int one,int two) { return (int)(0xF9F66090L >> (2*(one*4 + two)))%4; } 

Daha çox bitwise variant:

Bu, hər şeyin 2-dən çox olduğu faktını istifadə edir

 public int fightMath(int one,int two) { return (0xF9F66090 >> ((one << 3) | (two << 1)))  0x3; } 

Sehrli Sabitin mənşəyi

border=0

Nə deyə bilərəm Dünya sihirlərə ehtiyac duyur, bəzən bir şeyin olma ehtimalı onun yaradılmasını tələb edir.

OP problemini həll edən funksiyanın mahiyyəti {0,1,2,3} aralığında iki ədəd (bir, iki), sahələr (0,1,2,3) bir xəritəsidir. Cavabların hər biri bu kartı necə yerinə yetirməyə yaxın oldu.

Bundan əlavə, bir sıra cavablarda sorunun təkrarlanması iki nişanlı 4 nömrəli N (bir, iki) nömrəli 1 nömrədir, burada bir rəqəmli 1, iki rəqəm 2 və N = 4 * bir + iki ədəddir; N = {0,1,2, ..., 15} - on altı fərqli dəyərlər əhəmiyyətlidir. Funksiyanın çıxış siqnalının 1 rəqəmli nömrəli sayı 4 (0,1,2,3) - 4 fərqli dəyərlər də vacibdir.

İndi bir nömrəli baz sayı 4 rəqəmli 2 nömrəli baz nömrəsi kimi ifadə edilə bilər; {0,1,2,3} = {00,01,10,11} və buna görə hər çıxış yalnız iki bit ilə kodlana bilər. Üst yalnız 16 müxtəlif çıxışı var, belə ki, bütün kartı kodlaşdırmaq üçün lazım olan bütün 16 * 2 = 32 bit; Bunların hamısı 1 tamsayıya yerləşdirilə bilər.

M sabitliyə malik olan m (0) bitləri M [0: 1], m (1) bit M [2: 3] ilə kodlanır və m (n) bitlərdə M [n * 2 : n * 2 + 1].

Qalan hər şey indeksləmə və sabitin sağ tərəfini geri qaytarmaqdır, bu halda M-i sağa 2 * N dəfə köçürə və 2 ən az əhəmiyyətli biti (M → 2 * N) və 0x3-ə ala bilərsiniz. İfadələr (bir <3) və (iki <1) sadəcə məlumatları çarparaq, 2 * x = x <1 və 8 * x = x <3 olduğuna diqqət çəkir.

200
19 марта '14 в 18:56 2014-03-19 18:56 cavab 19 mart '14 'də saat 18:56' də verilir 2014-03-19 18:56

JAB istisna olmaqla təqdim edilən həllərdən heç birini sevmirdim. Başqalarının heç biri kodu oxumaq və hesablanılanları anlamaq asanlaşdırır .

Bu kodu necə yazacağam - yalnız C # deyil, Java deyil, ancaq bir şəkil alırsınız:

 const bool t = true; const bool f = false; static readonly bool[,] attackResult = { { f, f, t, f }, { f, f, f, t }, { f, t, t, t }, { t, f, t, t } }; [Flags] enum HitResult { Neither = 0, PlayerOne = 1, PlayerTwo = 2, Both = PlayerOne | PlayerTwo } static HitResult ResolveAttack(int one, int two) { return (attackResult[one, two] ? HitResult.PlayerOne : HitResult.Neither) | (attackResult[two, one] ? HitResult.PlayerTwo : HitResult.Neither); } 

İndi burada hesablanmış nə daha aydındır: hücum altına düşənləri hesablayır və hər iki nəticəni qaytarır.

Ancaq bu daha yaxşı ola bilər; Boolean array bir qədər qeyri-şəffafdır. Mən stolda axtarış üçün yanaşmağı xoşlayıram, amma oyunun semantikasında nə nəzərdə tutulduğunu dəqiqləşdirəcək şəkildə yazmağa məcbur oluram. Yəni, "sıfır hücum və bir nəticənin qorunması" hədəfinə dəyməyib, bunun yerine "aşağı təsirli hücum və aşağı blok ilə təsir - təsirsiz" ifadəsini daha dəqiq ifadə etmək üçün bir yol tapın. Oyunun biznes məntiqini əks etdirən bir kod yaradın.

98
19 марта '14 в 18:48 2014-03-19 18:48 Cavab Eric Lippert tərəfindən verilir 19 Mart '14 18:48 2014-03-19 18:48

Nəticələri olan bir matris yarada bilərsiniz

 int[][] results = {{0, 0, 1, 2}, {0, 0, 2, 1},{2, 1, 3, 3},{2, 1, 3, 3}}; 

Qiymət qazanmaq istədiyiniz zaman istifadə edəcəksiniz

 public int fightMath(int one, int two) { return this.results[one][two]; } 
87
19 марта '14 в 12:33 2014-03-19 12:33 Cavab djm.im 19 mart '14 'də saat 12:33' də verilir 2014-03-19 12:33

Digər insanlar mənim orijinal fikirini - matrix metodunu təklif etdilər, amma bəyanatlar birləşməsindən başqa, bəzi fikirlərdən qaçındığınızdan əmin ola bilərsiniz ki, verilmiş arqumentlərin gözlənilən aralığında olması və yerin qaytarılması ilə (bəzi kodlaşdırma standartları Funksiyalar üçün bir nöqtəli exit funksiyasını gördüm, amma çox oxunuşda okların kodlaşdırılmasının qarşısını almaq üçün çox faydalı olduğunu və Java-da istisnaların yayılması ilə çox ciddi bir nöqtə olmadığını gördüm bu qaydalar hər hansı bir vəziyyətdədir, çünki metod daxilində hər hansı bir istisna istisna hər halda mümkün bir çıxış nöqtəsidir). Daxili keçidlər bir fürsətdir, amma burada yoxladığınız kiçik bir sıra dəyərlər üçün hesabatların daha sıx olmasını və xüsusilə proqramınız real-vaxtdan çox addım-addım işlədiyini bilmək üçün böyük performans fərqlərinə səbəb ola bilər.

 public int fightMath(int one, int two) { if (one > 3 || one < 0 || two > 3 || two < 0) { throw new IllegalArgumentException("Result is undefined for arguments outside the range [0, 3]"); } if (one <= 1) { if (two <= 1) return 0; if (two - one == 2) return 1; return 2; // two can only be 3 here, no need for an explicit conditional } // one >= 2 if (two >= 2) return 3; if (two == 1) return 1; return 2; // two can only be 0 here } 

Nəticədə, I / O nəticəsinin ekran hissələrinin qeyri-bərabər olması səbəbindən başqa haldan daha az oxunaqlı olur. Matrix tərzini onun sadəliyi və matrisi görmə qabiliyyətinə görə necə tənzimləyə bilərsiniz (baxmayaraq ki, bu Carnot xəritələrimdə xatirələrimə bağlıdır):

 int[][] results = {{0, 0, 1, 2}, {0, 0, 2, 1}, {2, 1, 3, 3}, {2, 1, 3, 3}}; 

Yeniləmə. Bloklama / vurma sözünüzü nəzərə alaraq, giriş və nəticələr üçün sayılan növlərin təyin edilmiş xüsusiyyətləri və atributlarını istifadə edən funksiyaya daha radikal bir dəyişiklik baş verir və nəticədə, daha çox oxunaqlı funksiyaya səbəb olan bir az maneə nəzərə alınmaq üçün nəticəni dəyişir.

 enum MoveType { ATTACK, BLOCK; } enum MoveHeight { HIGH, LOW; } enum Move { // Enum members can have properties/attributes/data members of their own ATTACK_HIGH(MoveType.ATTACK, MoveHeight.HIGH), ATTACK_LOW(MoveType.ATTACK, MoveHeight.LOW), BLOCK_HIGH(MoveType.BLOCK, MoveHeight.HIGH), BLOCK_LOW(MoveType.BLOCK, MoveHeight.LOW); public final MoveType type; public final MoveHeight height; private Move(MoveType type, MoveHeight height) { this.type = type; this.height = height; }  public boolean isAttack() { return this.type == MoveType.ATTACK; } } enum LandedHit { NEITHER, PLAYER_ONE, PLAYER_TWO, BOTH; } LandedHit fightMath(Move one, Move two) { // One is an attack, the other is a block if (one.type != two.type) { // attack at some height gets blocked by block at same height if (one.height == two.height) return LandedHit.NEITHER; // Either player 1 attacked or player 2 attacked; whoever did // lands a hit if (one.isAttack()) return LandedHit.PLAYER_ONE; return LandedHit.PLAYER_TWO; } // both attack if (one.isAttack()) return LandedHit.BOTH; // both block return LandedHit.NEITHER; } 

Daha çox yüksəkliklərdə bloklar / hücumlar əlavə etmək istəyirsinizsə, funksiyanı dəyişdirməlisiniz, sadəcə sayımlar; Əlavə növ hərəkətləri əlavə etmək funksiyanı dəyişdirməyi tələb edə bilər. Bundan əlavə, EnumSet s , əsas numaralandırma xüsusiyyətləri kimi əlavə EnumSet daha geniş istifadə edilə bilər. EnumSet<Move> attacks = EnumSet.of(Move.ATTACK_HIGH, Move.ATTACK_LOW, ...); move.type == MoveType.ATTACK istifadə EnumSet birbaşa bərabərlik çeklərindən bir qədər daha yavaş olmasına baxmayaraq, attacks.contains(move) etmir. ( move.type == MoveType.ATTACK .


Müvəffəqiyyətli bir blokun bir if (one.height == two.height) return LandedHit.NEITHER; on

 if (one.height == two.height) { // Successful block results in a counter against the attacker if (one.isAttack()) return LandedHit.PLAYER_TWO; return LandedHit.PLAYER_ONE; } 

Bununla yanaşı, bir üçtərəfli operatorla ( boolean_expression ? result_if_true : result_if_false ) kodları daha kompakt edə bilər (məsələn, əvvəlki return one.isAttack() ? LandedHit.PLAYER_TWO : LandedHit.PLAYER_ONE; ). daha çətin oxunan oneliners gətirib çıxara bilər, ona görə də daha kompleks dallanma üçün məsləhət verməyəcəyəm.

69
19 марта '14 в 16:16 2014-03-19 16:16 Cavab JAB 19 Mart '14 'də 16:16' də verilir 2014-03-19 16:16

Niyə bir sıra istifadə etmirsiniz?

Başından başlayacağam. Bir nümunə görürəm, dəyərlər 0-dan 3-ə çıxır və bütün mümkün dəyərləri tutmaq istəyirsən. Bu sizin masanızdır:

 0  0 = 0 0  1 = 0 0  2 = 1 0  3 = 2 1  0 = 0 1  1 = 0 1  2 = 2 1  3 = 1 2  0 = 2 2  1 = 1 2  2 = 3 2  3 = 3 3  0 = 2 3  1 = 1 3  2 = 3 3  3 = 3 

bu ikili tabloya baxdığımızda aşağıdakı nəticələr görürük:

 00  00 = 00 00  01 = 00 00  10 = 01 00  11 = 10 01  00 = 00 01  01 = 00 01  10 = 10 01  11 = 01 10  00 = 10 10  01 = 01 10  10 = 11 10  11 = 11 11  00 = 10 11  01 = 01 11  10 = 11 11  11 = 11 

İndi bəlkə də bir neçə nümunəni görürsən, amma bir və iki dəyərləri birləşdirdiyimdə 0000, 0001, 0010, ..... 1110 və 1111 dəyərlərini istifadə etdiyini görürəm. İndi bir və iki dəyəri birləşdirək bir 4-bit tamsayı etmək.

 0000 = 00 0001 = 00 0010 = 01 0011 = 10 0100 = 00 0101 = 00 0110 = 10 0111 = 01 1000 = 10 1001 = 01 1010 = 11 1011 = 11 1100 = 10 1101 = 01 1110 = 11 1111 = 11 

Onu decimal dəyərlərə çevirdiyimizdə, biz bir və iki birləşmənin indeks kimi istifadə oluna biləcəyi çox dəyərli bir sıra görürük:

 0 = 0 1 = 0 2 = 1 3 = 2 4 = 0 5 = 0 6 = 2 7 = 1 8 = 2 9 = 1 10 = 3 11 = 3 12 = 2 13 = 1 14 = 3 15 = 3 

Sonra dizi 0, 0, 1, 2, 0, 0, 2, 1, 2, 1, 3, 3, 2, 1, 3, 3dir.

Mən bir Java proqramçı deyiləm, amma əgər bütün ifadələrdən xilas olsanız və bu kimi yazarsanız:

 int[] myIntArray = {0, 0, 1, 2, 0, 0, 2, 1, 2, 1, 3, 3, 2, 1, 3, 3}; result = myIntArray[one * 4 + two]; 

Shift bitinin çarpmadan daha sürətli olub olmadığını bilmirəm. Amma bir cəhdə dəyər ola bilər.

47
19 марта '14 в 17:21 2014-03-19 17:21 Dj bazzie wazzie tərəfindən verilmiş cavab 19 mart '14, 17:21 2014-03-19 17:21

Bir az bitmagic istifadə edir (birbaşa iki bit informasiya (aşağı / yüksək və hücum / blok) tutaraq bunu edirik):

Mən onu işlətməmişdim, sadəcə burada yığdım, ikiqat yoxlayın. Bu fikir əlbəttə ki işləyir. EDIT: İndi hər giriş üçün yoxlanılır, yaxşı işləyir.

 public int fightMath(int one, int two) { if(one<2  two<2){ //both players blocking return 0; // nobody hits }else if(one>1  two>1){ //both players attacking return 3; // both hit }else{ // some of them attack, other one blocks int different_height = (one ^ two)  1; // is 0 if they are both going for the same height - ie blocker wins, and 1 if height is different, thus attacker wins int attacker = one>1?1:0; // is 1 if one is the attacker, two is the blocker, and 0 if one is the blocker, two is the attacker return (attacker ^ different_height) + 1; } } 

Və ya iki bit məlumatı ayrı dəyişənlərə bölmək təklif edirəm? Tipik olaraq, yuxarıda olduğu kimi, bit əməliyyatlarına əsaslanan kod, adətən, saxlamaq üçün çox çətindir.

24
19 марта '14 в 17:40 2014-03-19 17:40 cavab 19 mart, '14 'də saat 17:40' də verilir. 2014-03-19 17:40

Dürüst olmaq lazımdır ki, hər kəsin öz stil kodu var. Performansı çox asılı olacağını düşünmədim. Şifrəyədək versiyasını istifadə etməkdən daha yaxşı başa düşsəniz, istifadə etməyə davam edin.

Ifs yuva edə bilərsiniz, buna görə də, əgər çeklər olduqda sonuncu üçün potensial bir az artım olardı. Amma əsas java kursu kontekstində bu, yəqin ki, faydalı olmaz.

 else if(one == 3  two == 3) { result = 3; } 

Bunun əvəzinə ...

 if(one == 0  two == 0) { result = 0; } else if(one == 0  two == 1) { result = 0; } else if(one == 0  two == 2) { result = 1; } else if(one == 0  two == 3) { result = 2; } 

Bilirsən ...

 if(one == 0) { if(two == 0) { result = 0; } else if(two == 1) { result = 0; } else if(two == 2) { result = 1; } else if(two == 3) { result = 2; } } 

Və yalnız onu istədiyiniz şəkildə yenidən formatlaşdırın.

Bu kod daha yaxşı etmir, amma mənim fikrimcə, bir qədər sürətləndirir.

19
19 марта '14 в 12:50 2014-03-19 12:50 Joe Harperin 19 Mart '14 'də saat 12:50' də verdiyi cavabı 2014-03-19 12:50

Nə bildiyimizi görək

1: cavablarınız P1 (oyunçu bir) və P2 (ikinci oyunçu) üçün simmetrikdir. Bir döyüş oyunu üçün mənalı, ancaq məntiqinizi yaxşılaşdırmaq üçün də istifadə edə bilərsiniz.

2: 3 atışları 0 atışları 2 vuruş 1 bit 3. Bu hallarda əhatə olunmayan yalnız hallar 0-a qarşı 1 və 2-ə qarşıdır. Başqa sözlə, unikal qalibiyyət masası belə görünür: 0 atış 2, 1 atış 3, 2 atış 1, 3 vuruş 0.

3: 0/1 birinə qarşı getmək, yəni kontaksız sarsıdıcı olsa, 2/3 hər birinə qarşı gedirsə,

Birincisi, qazandıqlarımız olub-olmadığını bizə bildirən birtərəfli funksiyanı quraq:

 // returns whether we beat our opponent public boolean doesBeat(int attacker, int defender) { int[] beats = {2, 3, 1, 0}; return defender == beats[attacker]; } 

Sonra son nəticəni tərtib etmək üçün bu funksiyadan istifadə edə bilərik:

 // returns the overall fight result // bit 0 = one hits // bit 1 = two hits public int fightMath(int one, int two) { // Check to see whether either has an outright winning combo if (doesBeat(one, two)) return 1; if (doesBeat(two, one)) return 2; // If both have 0/1 then its hitless draw but if both have 2/3 then they both hit. // We can check this by seeing whether the second bit is set and we need only check // one value as combinations where they don't both have 0/1 or 2/3 have already // been dealt with return (one  2) ? 3 : 0; } 

Çox cavablarda təklif olunan cədvəlin axtarışından daha mürəkkəb və yəqin ki, yavaş olmasına baxmayaraq, bu, əla bir metoddur, çünki həqiqətən kodunuzun məntiqini əhatə edir və kodunuzu oxuyan hər kəsə təsvir edir. Hesab edirəm ki, bu, daha səmərəlidir.

(Bir sözlə, hər hansı bir Java məndən bəri bir müddət keçdi, sintaksis söndürülsə, üzr istəmirəm, bir az yanlış olduğumu hələ də açıq-aşkar ümid edirəm)

Yeri gəlmişkən, 0-3 açıq-aydın bir şey deməkdir; onlar özbaşına dəyərlər deyildir, ona görə də onları çağırırlar.

12
20 марта '14 в 14:44 2014-03-20 14:44 Cavab Jack Aidley tərəfindən 20 Mart 'da 14:44' də veriləcək 2014-03-20 14:44

Ümid edirəm ki, məntiqini düzgün başa düşürəm. Necə bir şey haqqında:

 public int fightMath (int one, int two) { int oneHit = ((one == 3  two != 1) || (one == 2  two != 0)) ? 1 : 0; int twoHit = ((two == 3  one != 1) || (two == 2  one != 0)) ? 2 : 0; return oneHit+twoHit; } 

Yüksək və ya aşağı səviyyəli bir vuruşun yoxlanılmaması, eyni zamanda ikinci oyunçu üçün bərabərdir.

Düzəliş: Alqoritm tamamilə başa düşülməmişdi, mən onu anlamadım (eli sayəsində), bloklandığı zaman "vurdu":

 public int fightMath (int one, int two) { int oneAttack = ((one == 3  two != 1) || (one == 2  two != 0)) ? 1 : (one >= 2) ? 2 : 0; int twoAttack = ((two == 3  one != 1) || (two == 2  one != 0)) ? 2 : (two >= 2) ? 1 : 0; return oneAttack | twoAttack; } 
11
20 марта '14 в 5:20 2014-03-20 05:20 20 Mart 'da Chris tərəfindən verilən cavab 5:20' də 2014-03-20 05:20

Java ilə heç bir təcrübəm yoxdur, buna görə bəzi yazı tipləri ola bilər. Kodu pseudocode olaraq nəzərdən keçirin.

Sadə bir keçid ilə gedərdim. Bunu etmək üçün ayrı bir otaq reytinqinə ehtiyac duyacaqsınız. Bununla belə, bu halda, 0 <= one < 4 <= 90 <= two < 4 <= 9 olduğundan, ikisini one 10-a çarparaq two əlavə edərək int intiminə int çevirə bilərik. Sonra nəticələnən nöqtədə keçidi aşağıdakı kimi istifadə edin:

 public int fightMath(int one, int two) { // Convert one and two to a single variable in base 10 int evaluate = one * 10 + two; switch(evaluate) { // I'd consider a comment in each line here and in the original code // for clarity case 0: result = 0; break; case 1: result = 0; break; case 1: result = 0; break; case 2: result = 1; break; case 3: result = 2; break; case 10: result = 0; break; case 11: result = 0; break; case 12: result = 2; break; case 13: result = 1; break; case 20: result = 2; break; case 21: result = 1; break; case 22: result = 3; break; case 23: result = 3; break; case 30: result = 1; break; case 31: result = 2; break; case 32: result = 3; break; case 33: result = 3; break; } return result; } 

Yalnız bir nəzəri kod kimi göstərmək istədiyim başqa bir qısa metoddur. Ancaq mən bunu istifadə etməyəcəyəm, çünki adətən daha çox məşğul olmaq istəmədiyiniz bəzi əlavə mürəkkəbliyi var. Əlavə mürəkkəblik saya 4-dən gəlir, hesab sayı 0, 1, 2, 3, 10, 11, 12, 13, 20, ...

 public int fightMath(int one, int two) { // Convert one and two to a single variable in base 4 int evaluate = one * 4 + two; allresults = new int[] { 0, 0, 1, 2, 0, 0, 2, 1, 2, 1, 3, 3, 1, 2, 3, 3 }; return allresults[evaluate]; } 

Java'dan bir şey qaçırdığım halda əslində əlavə bir qeyd. PHP-də bunu edəcəyəm:

 function fightMath($one, $two) { // Convert one and two to a single variable in base 4 $evaluate = $one * 10 + $two; $allresults = array( 0 => 0, 1 => 0, 2 => 1, 3 => 2, 10 => 0, 11 => 0, 12 => 2, 13 => 1, 20 => 2, 21 => 1, 22 => 3, 23 => 3, 30 => 1, 31 => 2, 32 => 3, 33 => 3 ); return $allresults[$evaluate]; } 
10
19 марта '14 в 20:19 2014-03-19 20:19 Cavab Fransisko Presencia'ya 19 Mart 'da 20:19' də veriləcək 2014-03-19 20:19

if şərtləri içərisində qoyduğunuza görə başqa bir yoldur.
result üzvünü istifadə etmir və hər hansı bir vəziyyəti dəyişməyəcəyini unutmayın.

 public int fightMath(int one, int two) { if (one == 0) { if (two == 0) { return 0; } if (two == 1) { return 0; } if (two == 2) { return 1; } if (two == 3) { return 2; } } if (one == 1) { if (two == 0) { return 0; } if (two == 1) { return 0; } if (two == 2) { return 2; } if (two == 3) { return 1; } } if (one == 2) { if (two == 0) { return 2; } if (two == 1) { return 1; } if (two == 2) { return 3; } if (two == 3) { return 3; } } if (one == 3) { if (two == 0) { return 1; } if (two == 1) { return 2; } if (two == 2) { return 3; } if (two == 3) { return 3; } } return DEFAULT_RESULT; } 
7
19 марта '14 в 21:42 2014-03-19 21:42 Cavab Nik Dandoulakis tərəfindən 19 Mart '14 'da 21:42' də verilir 2014-03-19 21:42

Mənə baş verən ilk şey, əsasən, Francisco Presencia verdiyi eyni cavabı idi, lakin bir qədər optimallaşdırıldı:

 public int fightMath(int one, int two) { switch (one*10 + two) { case 0: case 1: case 10: case 11: return 0; case 2: case 13: case 21: case 30: return 1; case 3: case 12: case 20: case 31: return 2; case 22: case 23: case 32: case 33: return 3; } } 

Siz son işi (3) üçüncü halda edərkən optimize edə bilərsiniz:

  //case 22: //case 23: //case 32: //case 33: default: return 3; 

Bu metodun üstünlüyü, onetwo dəyər üçün dəyərlərin digər təklif olunan üsullardan birinə nisbətən uyğun olduğunu görmək daha asandır.

6
20 марта '14 в 20:52 2014-03-20 20:52 Cavab David R Tribble tərəfindən verilir 20 Mart 'da 20:52 2014-03-20 20:52

Bir keçid qutusu istifadə edin . ..

Daha ətraflı məlumat üçün buraya və ya buraya baxın.

 switch (expression) { case constant: statements; break; [ case constant-2: statements; break; ] ... [ default: statements; break; ] ... } 

Bir neçə şərt əlavə edə bilərsiniz (eyni zamanda deyil) və hətta başqa hallarda yerinə yetirilməyən default parametrdən istifadə edə bilərsiniz .

PS: Yalnız bir şərt yerinə yetirilməlidir.

Eyni zamanda iki şərt meydana gəlir. Mən keçid istifadə edilə bilər deyə düşünmürəm. Ancaq kodu buradan azaldın.

Java operatoru bir neçə haldır

6
19 марта '14 в 12:27 2014-03-19 12:27 Cavab 19: 14 'də Nevin Madhukar K tərəfindən 12:27 2014-03-19 12:27
 ((two> 
6
21 марта '14 в 11:04 2014-03-21 11:04 Cavab Dawood ibn Kareem tərəfindən 21 Mart '14 'də 11:04' də veriləcək 2014-03-21 11:04

Əgər halda> halda mutiple istifadə edə bilərsiniz

Biz də iki dəyişən olduğunuzdan bəhs edirik ki, onları bir keçiddə istifadə etmək üçün iki dəyişən birləşdirməlisiniz.

İki dəyişənliyi idarə etmək üçün bu java operator bildirişini yoxlayın ?

4
19 марта '14 в 12:27 2014-03-19 12:27 Cavab 19 mart 14: 14-də Rahul Tripathi tərəfindən verilir. 2014-03-19 12:27

Yaxşı bir nöqtə qaydaları mətn olaraq təyin etmək olar, daha sonra doğru formulu daha asanlıqla əldə edə bilərsiniz. Bu laalto gözəl array baxımından alınır:

 { 0, 0, 1, 2 }, { 0, 0, 2, 1 }, { 2, 1, 3, 3 }, { 1, 2, 3, 3 } 

Burada ümumi şərhlərə baxacağıq, ancaq onları qaydalara görə təsvir etməliyəm:

 if(one<2) // left half { if(two<2) // upper left half { result = 0; //neither hits } else // lower left half { result = 1+(one+two)%2; //p2 hits if sum is even } } else // right half { if(two<2) // upper right half { result = 1+(one+two+1)%2; //p1 hits if sum is even } else // lower right half { return 3; //both hit } } 

Əlbəttə ki, onu daha az miqdarda kodlaşdırmaq olar, amma bir qayda olaraq, nə kodladığınızı anlamaq və kompakt bir həll tapmaq deyil, pis bir fikirdir.

 if((one<2) result = 0; //top left else if((one>1) result = 3; //bottom right else result = 1+(one+two+((one>1)?1:0))%2; //no idea what that means 

P1 / p2 kompleks xitlərinin bəzi şərhləri gözəl olardı, maraqlı görünür!

3
21 марта '14 в 2:23 2014-03-21 02:23 Cavab Marcellus 21 mart '14 'də 2:23' də verilir 2014-03-21 02:23

Самое короткое и доступное для чтения решение:

 static public int fightMath(int one, int two) { if (one < 2  two < 2) return 0; if (one > 1  two > 1) return 3; int n = (one + two) % 2; return one < two ? 1 + n : 2 - n; } 

или даже короче:

 static public int fightMath(int one, int two) { if (one / 2 == two / 2) return (one / 2) * 3; return 1 + (one + two + one / 2) % 2; } 

Не содержит никаких "магических" чисел;) Надеюсь, что это поможет.

3
ответ дан PW 26 марта '14 в 16:04 2014-03-26 16:04

Когда я рисую таблицу между одним/двумя и результатом, я вижу один шаблон,

 if(one<2  two <2) result=0; return; 

Вышеуказанное сократило бы по крайней мере 3 заявления. Я не вижу заданного шаблона, и я не могу много узнать из приведенного кода, но если такая логика может быть выведена, она сократила бы количество операторов if.

Bu kömək edir.

3
ответ дан AnonNihcas 19 марта '14 в 12:44 2014-03-19 12:44

static int val(int i, int u){ int q = (i 1) ^ (u 1); return ((i >> 1) << (1 ^ q))|((u >> 1) << q); }

2
ответ дан user1837841 04 апр. '14 в 4:21 2014-04-04 04:21

Мне лично нравится каскадировать тернарные операторы:

 int result = condition1 ? result1 : condition2 ? result2 : condition3 ? result3 : resultElse; 

Но в вашем случае вы можете использовать:

 final int[] result = new int[] { 0, 0, 1, 2, 0, 0, 2, 1, 2, 1, 3, 3, 1, 2, 3, 3 }; public int fightMath(int one, int two) { return result[one*4 + two]; } 

Или вы можете заметить шаблон в битах:

 one two result section 1: higher bits are equals => both result bits are equals to that higher bits 00 00 00 00 01 00 01 00 00 01 01 00 10 10 11 10 11 11 11 10 11 11 11 11 section 2: higher bits are different => lower result bit is inverse of lower bit of 'two' higher result bit is lower bit of 'two' 00 10 01 00 11 10 01 10 10 01 11 01 10 00 10 10 01 01 11 00 01 11 01 10 

Итак, вы можете использовать магию:

 int fightMath(int one, int two) { int b1 = one  2, b2 = two  2; if (b1 == b2) return b1 | (b1 >> 1); b1 = two  1; return (b1 << 1) | (~b1); } 
1
ответ дан Kirill Gamazkov 20 марта '14 в 22:45 2014-03-20 22:45

Я бы использовал карту, либо HashMap, либо TreeMap

Особенно, если параметры не находятся в форме 0 <= X < N

Как набор случайных положительных целых чисел.

kodu

 public class MyMap { private TreeMap<String,Integer> map; public MyMap () { map = new TreeMap<String,Integer> (); } public void put (int key1, int key2, Integer value) { String key = (key1+":"+key2); map.put(key, new Integer(value)); } public Integer get (int key1, int key2) { String key = (key1+":"+key2); return map.get(key); } } 
1
ответ дан Khaled.K 26 марта '14 в 8:30 2014-03-26 08:30

Благодаря @Joe Harper, когда я закончил тем, что использовал его вариант ответа. Чтобы уменьшить его, так как 2 результата на 4 были одинаковыми, я уменьшил его.

В какой-то момент я могу вернуться к этому вопросу, но если нет значительного сопротивления, вызванного несколькими if -statements, то я сохраню это сейчас. Я еще раз рассмотрю матрицы таблиц и решения операторов операторов.

 public int fightMath(int one, int two) { if (one == 0) { if (two == 2) { result = 1; } else if(two == 3) { result = 2; } else { result = 0; } } else if(one == 1) { if (two == 2) { result = 2; } else if(two == 3) { result = 1; } else { result = 0; } } else if(one == 2) { if (two == 0) { result = 2; } else if(two == 1) { result = 1; } else { result = 3; } } else if(one == 3) { if (two == 0) { result = 1; } else if(two == 1) { result = 2; } else { result = 3; } } return result; } 
1
ответ дан TomFirth 19 марта '14 в 15:45 2014-03-19 15:45

Здесь довольно сжатая версия, похожая на JAB-ответ . Это использует карту для хранения, которая движется над другими.

 public enum Result { P1Win, P2Win, BothWin, NeitherWin; } public enum Move { BLOCK_HIGH, BLOCK_LOW, ATTACK_HIGH, ATTACK_LOW; static final Map<Move, List<Move>> beats = new EnumMap<Move, List<Move>>( Move.class); static { beats.put(BLOCK_HIGH, new ArrayList<Move>()); beats.put(BLOCK_LOW, new ArrayList<Move>()); beats.put(ATTACK_HIGH, Arrays.asList(ATTACK_LOW, BLOCK_LOW)); beats.put(ATTACK_LOW, Arrays.asList(ATTACK_HIGH, BLOCK_HIGH)); } public static Result compare(Move p1Move, Move p2Move) { boolean p1Wins = beats.get(p1Move).contains(p2Move); boolean p2Wins = beats.get(p2Move).contains(p1Move); if (p1Wins) { return (p2Wins) ? Result.BothWin : Result.P1Win; } if (p2Wins) { return (p1Wins) ? Result.BothWin : Result.P2Win; } return Result.NeitherWin; } } 

Məsələn:

 System.out.println(Move.compare(Move.ATTACK_HIGH, Move.BLOCK_LOW)); 

Yazdırın

 P1Win 
1
ответ дан Duncan Jones 24 марта '14 в 19:32 2014-03-24 19:32
  • Используйте константы или перечисления, чтобы сделать код более удобочитаемым
  • Попробуйте разделить код на несколько функций.
  • Попробуйте использовать симметрию проблемы

Вот пример, как это могло бы выглядеть, но использование ints здесь по-прежнему выглядит уродливым:

 static final int BLOCK_HIGH = 0; static final int BLOCK_LOW = 1; static final int ATTACK_HIGH = 2; static final int ATTACK_LOW = 3; public static int fightMath(int one, int two) { boolean player1Wins = handleAttack(one, two); boolean player2Wins = handleAttack(two, one); return encodeResult(player1Wins, player2Wins); } private static boolean handleAttack(int one, int two) { return one == ATTACK_HIGH  two != BLOCK_HIGH || one == ATTACK_LOW  two != BLOCK_LOW || one == BLOCK_HIGH  two == ATTACK_HIGH || one == BLOCK_LOW  two == ATTACK_LOW; } private static int encodeResult(boolean player1Wins, boolean player2Wins) { return (player1Wins ? 1 : 0) + (player2Wins ? 2 : 0); } 

Было бы лучше использовать структурированный тип для ввода и вывода. На входе фактически есть два поля: позиция и тип (блок или атака). Выход также имеет два поля: player1Wins и player2Wins. Кодирование этого в одно целое затрудняет чтение кода.

 class PlayerMove { PlayerMovePosition pos; PlayerMoveType type; } enum PlayerMovePosition { HIGH,LOW } enum PlayerMoveType { BLOCK,ATTACK } class AttackResult { boolean player1Wins; boolean player2Wins; public AttackResult(boolean player1Wins, boolean player2Wins) { this.player1Wins = player1Wins; this.player2Wins = player2Wins; } } AttackResult fightMath(PlayerMove a, PlayerMove b) { return new AttackResult(isWinningMove(a, b), isWinningMove(b, a)); } boolean isWinningMove(PlayerMove a, PlayerMove b) { return a.type == PlayerMoveType.ATTACK  !successfulBlock(b, a) || successfulBlock(a, b); } boolean successfulBlock(PlayerMove a, PlayerMove b) { return a.type == PlayerMoveType.BLOCK  b.type == PlayerMoveType.ATTACK  a.pos == b.pos; } 

К сожалению, Java не очень хорошо выражает эти типы данных.

0
ответ дан peq 29 марта '14 в 21:03 2014-03-29 21:03

Вместо этого сделайте что-нибудь вроде этого

  public int fightMath(int one, int two) { return Calculate(one,two) } private int Calculate(int one,int two){ if (one==0){ if(two==0){ //return value} }else if (one==1){ // return value as per condtiion } } 
-2
ответ дан onkar 19 марта '14 в 12:32 2014-03-19 12:32

Другие вопросы по меткам или Задайте вопрос