Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 19

0
votes
answers
11 views
+10

字符串字計數器

0

我必須打印一個字符串中的字數統計N次?字符串字計數器

例如:

一二三四三兩個五

輸出:3

由於一個,四和五隻出現一次。

我的代碼顯示我的輸出爲1

什麼是錯我的代碼和邏輯?謝謝。

import java.util.*; 
public class Hello { 

    public static void main(String[] args) { 
     Scanner scan=new Scanner(System.in); 
     String s=scan.nextLine(),b; 
     int n=scan.nextInt(); 
     int c=0,f=0,i; 
     String[] a=s.split(" "); 
     for(i=0;i<a.length;i++) 
     { 
      b=a[i]; 
      for(int j=i+1;j<a.length;j++) 
      { 
      if(b.equalsIgnoreCase(a[j])) 
      { 
       c++; 
      } 

      } 
      if(n==c) 
      { 
       f++; 
      } 
      else 
      { 
       c=0; 

      } 
     } 
     System.out.print(f); 

    } 
} 
+2

我建議通過它符合一個調試器步進一行。 – notyou

+0

你永遠不會重置'i'變量。 –

沙发
0
1

我看到三個原因導致您的結果不正確。

第一個是c 如果一個字在這裏只有一次,那麼if聲明if(b.equalsIgnoreCase(a[j]))永遠不會爲真。這意味着c將永遠等於0 所以,你需要使用1作爲默認值c還是應該使用下面的語句if (n == c + 1)

第二點是,你應該重新設置檢查c值值爲c,即使它等於n

然後用這雙for循環:

for (i = 0; i < a.length; i++) { 
    b = a[i]; 
    for (int j = i + 1; j < a.length; j++) { 

當你尋找這是一個值。有一次而已,每一個單詞的最後一個實例也會被計算在內。 有很多方法可以解決這個問題。其中之一是使用Set<String>,只計算以前沒有使用過的詞。

所以最終你將有類似的東西:

int c=1,f=0,i; 
String[] a=s.split(" "); 
Set<String> words = new HashSet<>(); 
for (i = 0; i < a.length; i++) { 
    b = a[i]; 
    if (words.add(b)) { 
    for (int j = i + 1; j < a.length; j++) { 
     if (b.equalsIgnoreCase(a[j])) { 
     c++; 
     } 
    } 
    if (n == c) { 
     f++; 
    } 
    c = 1; 
    } 
} 
板凳
0
0

我想這是因爲當n == c時你不初始化C。因此它在一個和一個匹配後增加到1。它運作不好。它應該爲0每個循環 也爲什麼j從i + 1開始?每個循環後,它會逐一失去比較自[j]越來越小。它應該始終包含完整輸入號碼列表

9
votes
answers
23 views
+10

How can Sphinx do its sorting so fast?

Let's say I search for "baby". Sphinx will grab all the documents that have "baby" in it, and then sort it using my own algorithm. (EXTENDED mode).

The question is, how can it sort so fast? How does it grab millions of records and then sort them within milliseconds?

沙发
+90

哦,你問的是魔法。Sphinx(和Lucene以及許多其他搜索引擎)正在使用倒排索引

基本上,每個文件都被切成標記; 搜索索引包括從標記到稱為發布列表的文檔的映射處理查詢包括查看查詢術語的發布列表和查找匹配文檔。為了加快速度,令牌將存儲為整數列表。通過壓縮索引可以使這更有效

Very interesting read (so far...) thanks for the link :) – Matthieu M. Nov 8 '10 at 11:20

0
votes
answers
29 views
+10

復發T(n)= T(n - log(n))+ 1

0

你如何找到這樣的遞推關係的嚴格界限?這是一個重要的問題,我們期望證明m/log(m)是嚴格的漸近界。我嘗試使用感應,但它似乎無處可去。這是要麼我缺少對數規則或有更多的東西。復發T(n)= T(n - log(n))+ 1

+0

告訴我們你如何開始歸納,也許有人可以從那裏幫助你。 – ShadowMitia

沙发
0
1

感應。假設所有k < nT(k) <= C k/log k對於某些C

展開復發(n/2)/log(n/2)次,更換log(.)log(n/2)(我們利用的事實,即T(n)log(n)是單調函數)。也就是說,

T(n) <= T(n - log(n/2) * (n/2)/log(n/2)) + (n/2)/log(n/2)

T(n) <= T(n/2) + (n/2)/log(n/2)

T(n) <= C (n/2)/log(n/2) + (n/2)/log(n/2)

現在你要證明右邊的表達被C n/log n界。算術和找到這樣的C是作爲一個練習。

+0

我不同意。我認爲解決方案的形式應該是: '(n-log(n))/(log(n-log(n)))' – ugar

+0

@nomadov它取決於你需要的近似程度。 –

+0

如何展開次數?(n/2)/ log(n/2)次?我不明白你是如何得到T(n)<= T(n-log(n/2)*(n/2)/ log(n/2))+(n/2)/ log(n/2 )' – ugar

0
votes
answers
20 views
+10

Python優化算法調整線越過儘可能多的點

1

這是我的第一篇文章。對不起,如果它看起來像一堵文字牆。 希望有人能夠理解我的問題,並提供一個可以做到這一點的示例模塊,或者一些代碼來嘗試。 我正在與時間序列CSV數據時,下面的實施例的行,列是(日期時間,O,H,L,C)Python優化算法調整線越過儘可能多的點

1999-10-26 21:00:00 68.81 68.83 68.07 68.19 
1999-10-27 21:00:00 68.19 68.2 66.83 67.43 
1999-10-28 21:00:00 67.43 68.06 66.91 68.06 
1999-10-29 21:00:00 68.06 68.11 66.31 66.66 
1999-01-11 22:00:00 66.66 67.15 66.09 66.63 
1999-02-11 22:00:00 66.63 67.38 66.42 66.58 
1999-03-11 22:00:00 66.58 67.73 66.42 67.48 
1999-04-11 22:00:00 67.48 67.81 66.54 66.76 
1999-05-11 22:00:00 66.76 68.2 66.54 67.87 

哪個是所謂燭臺在金融價格數據,並可以被表示視覺上像這樣:

enter image description here

現在,我想實現的是自動繪製,將橫看成燈芯(垂直線的燭臺)儘可能一條線,而不是跨越超過規定的公差更蠟燭體數量(綠色或紅色區域)

希望這是有道理的。 示例。穿越儘可能多的燈芯(在這種情況下蠟燭下面)的線將開始在位置4,大約66.4,並且具有上升斜率,直到位置9大約在66.55 ...

我想象的線條基於上述

畫面是否有一個模塊,可以做到這一點,如果我提供了一個首發位置? 基本上,像一條最合適的線,但實際上穿過所有的點(一個點是一條垂直線,所以在x軸上的範圍),同時避免穿過紅色/綠色區域,所以本質上是趨勢線(不是彎曲的)

如果這太複雜了,因爲這條線是對角線,那麼您最好還是提供一個水平線來做相同的示例(從x軸只有一個值)。例如,如最後兩條記錄的數據L(第四列)所示,66.54的值也可以起作用(它將穿過所有燈芯,並觸摸最後兩條記錄) 請參閱黃線交叉或觸摸所有低燈芯

在這種情況下值

(x軸)的起始位置蠟燭無關緊要的,並調節得

線在預定的點(例如,我可以選擇在位置5將開始圖像,這是最低點),並繼續,直到獲得最佳效果,以便它可以在任何地方停下來。然後我計劃使用基於這兩點的角度值來擴展這條線。因此,我要查找的輸出實際上只是線((x,y)的對角線趨勢線)或簡單的x軸值(水平線)的終點位置。起點將被選擇(A),並且終點基於算法優化,其中線應儘可能多地跨越蠟燭的垂直線(只看向起點的右側),但保持跨越的計數蠟燭身體區域低於公認的閾值容限,直到找不到更好的解決方案。 (B)

我已經看過佈雷森漢姆的線算法和一堆其他人,但沒有看到如何在Python時間序列數據中實現這個。我希望這很容易就像使用fbprophet

真正的csv文件重達500MB,幷包含多達600萬行 我寧願一個窮舉算法,而不是遺傳,每次都會產生不同的結果...

我已經就如何嘗試在此期間做到這一點的一些想法,但找不到與示例中的任意合適的模塊,以加快這一進程

如果這還不清楚......我想最大化在蠟燭中間(圖片上的白線)所看到的線條穿過垂直線的次數,同時保持允許跨越限制爲所選值的綠色/紅色區域的次數。

我用pyqtgraph爲visuallisation 實施例的代碼,使劇情: http://www.pyqtgraph.org/downloads/0.10.0/pyqtgraph-0.10.0-deb/pyqtgraph-0.10.0/examples/customGraphicsItem.py

沙发
0
0

如果正確地明白,要最大化的傾斜線的交叉點的數目與一組等間距的垂直線段的(交叉燭臺的允許/禁止使得問題有點模糊)。

如果我也理解正確的話,一次可以有一百萬段。

如果線的斜率是固定的,讓m,可以以這樣的方式剪切空間使該行成爲水平並且端點是垂直通過量m.i用於段i(假設單元間距)平移。

然後,通過增加縱座標對端點進行排序,您可以在翻譯線條時輕鬆獲得水平重疊的段數。這需要N Log N操作進行排序,N操作來構造計數功能。

現在對於任何斜率,您都可以獲得可能的最大交叉數。如果此功能足夠平滑,可以通過黃金比例法或類似方法搜索此功能的最大值。

+0

感謝您的建議,並指出我在正確的方向。經過進一步的研究,我相信我正在尋找的是一種算法,以返回+1或-1皮爾遜相關係數的所有可能性,其中元素多於2。 – Cactus

0
votes
answers
11 views
+10

需要按書名打印書的作者

-1

我不知道如何通過輸入書的標題來打印書的作者。本書及其作者通過文本文件中的管道字符(「|」)相互分隔。我只知道如何打印第一本書的作者。需要按書名打印書的作者

def load_library(a): 
    s = open(a,'r') 
    while True: 
     theline = s.readline() 
     razdel = theline.split('|') 
     if len(theline) == 0: 
      break 
     books_authors=razdel.pop(1) 
     return books_authors 
    return razdel 
    s.close() 

if __name__=='__main__': 
    result = load_library('books.txt') 
    print(result) 
+0

將字典映射到作者作爲解決方案就足夠了? –

沙发
0
0

您的函數在while循環中返回調用,而不是打印/保存到列表中。所以只有第一行被讀取。

def load_library(a): 
    s = open(a,'r') 
    result = [] 
    while True: 
      theline = s.readline() 
      razdel = theline.split('|') 
      if len(theline) == 0: 
       break 
      books_authors=razdel.pop(1) 
      result.append(book_authors) 
    s.close() 
    return result 




if __name__=='__main__': 
    result = load_library('books.txt') 
    print(result) 
+0

只需要輸入圖書標題的一位作者,並非所有作者 –

+0

都可以提及關於books.txt中數據格式的更多信息嗎? – skb

板凳
0
0

假設您的文本文件以表格格式排序|作者,這可以做到。

import csv 

#read csv sheet into dict 
D={} 
with open(filename,'r') as f: 
    fcsv=csv.reader(f,delimiter='|') 
    for row in fcsv: 
     D[row[0]]=row[1] 

print D[booktitle] 
地板
0
0

如果'books.txt'文件包含這些條目:

Title1|Joe Blow 
Title2|Jane Doe 
Title Number Three|Henry Longwords 

你可以建立一個字典,從它那有書名爲鍵和寫作者(S)的列表。這是我我說的:

from pprint import pprint 

def load_library(filename): 
    authors_by_book = {} 
    with open(filename) as file: 
     for line in file: 
      author, title = line.strip().split('|') 
      authors_by_book.setdefault(author, []).append(title) 

    return authors_by_book 


if __name__=='__main__': 
    authors_by_book = load_library('books.txt') 
    pprint(authors_by_book) 
    print() 
    print('Author(s) of {}: {}'.format('Title2', authors_by_book['Title2'])) 

輸出:

{'Title Number Three': ['Henry Longwords'], 
'Title1': ['Joe Blow'], 
'Title2': ['Jane Doe']} 

Author(s) of Title2: ['Jane Doe'] 

原因與每個鍵關聯的值是一個列表,是因爲一本書可以有多個作者。這可能發生,如果相同的標題在'bookts.txt'文件出現了不止一次,像這樣:

Deep Throat|Bob Woodward 
Deep Throat|Carl Bernstein 

您可以修改代碼以支持其在單個條目中列出多個作者,如:

Deep Throat|Bob Woodward|Carl Bernstein 

如果你需要/想要。

+0

是的,這是有效的。謝啦!但是如果我也有相同的txt文件,但是現在我需要找到給定作者的所有書籍。如何編寫這個反轉的程序? –

+0

@Kapa:當然它有效,它是測試代碼。 ';¬)'。請考慮接受它(請參閱[**當某人回答我的問題時該怎麼辦?**](http://stackoverflow.com/help/someone-answers)。 – martineau

+0

@Kapa:查找給定的所有書籍作者,你可以構造第二個名爲'books_by_author'的字典,並以類似於當前我的回答中的方式創建它,只是以相反順序指定的'author'和'title'。 – martineau

0
votes
answers
8 views
+10

如何在子字符串級別生成同音字符?

1

我想生成編程的單詞同音字。意思是聽起來類似於原始單詞的單詞。如何在子字符串級別生成同音字符?

我碰到過Soundex算法,但它只是用其他字符替換某些字符(如t而不是d)。是否有任何列表或算法有點複雜,至少意味着同音字子串?

重要的是,我想將它應用於不在字典中的單詞,意味着它不能依賴整個真實的單詞。

編輯:

輸入是一個字符串,他們往往是命名實體,因此在沒有真正的(同音字)詞典。一個例子可能是谷歌麥當勞(僅舉兩個流行的命名實體,但許多更不受歡迎)。

然後輸出是該字符串的(隨機)同音字。由於單詞經常有多個同音字,所以單個(隨機)單是我的目標。在谷歌的情況下,同音字可分別古格爾麥當勞麥當勞

+0

分享你的代碼,輸入和期望的輸出 – skrubber

沙发
0
0

如何做到這一點是一個研究課題。例如參見http://www.inf.ufpr.br/didonet/articles/2014_FPSS.pdf

但是,假設你想推出自己的。

第一步是弄清楚如何將給出的字母轉換成它聽起來像的表示。這是一個非常困難的問題,需要猜測。 (例如,什麼聲音「讀取」了?取決於你是否要閱讀,或者你已經閱讀!)但是text to phonemes converter表明阿拉伯已經解決了這個英語。

接下來,您會希望對詞典中的每個詞都進行此操作。假設你可以用一個字來做,那只是一個腳本。

然後,你會希望它存儲在一個數據結構中,你可以很容易地找到類似的聲音。原則上與用於拼寫自動更正的算法類型沒有區別。只能用音素而不是字母。您可以通過http://norvig.com/spell-correct.html瞭解如何做到這一點。或嘗試實施類似http://fastss.csg.uzh.ch/ifi-2007.02.pdf中所述的內容。

就是這樣。

+0

我在哪裏看到的問題是,我的字典不會包含像麥克唐納或格格爾這樣的詞 - 因此不會被認爲是同音詞,對嗎?爲了建立字典,我需要事先知道可能的同音詞。這與自動更正有所不同,因爲我想從Google轉到Gugel而不是Gugel到Google。 – ScientiaEtVeritas

+0

對。您需要提供所有可能的答案才能使用此方法。 – btilly

0
votes
answers
17 views
+10

爲什麼選擇排序不貪心

1

我發現選擇排序使用蠻力策略。不過,我認爲它使用貪婪策略。爲什麼選擇排序不貪心

爲什麼我認爲它使用貪婪:它在外循環和從i + 1到n-1從0到n-1。這真的很天真。它在每次迭代中選擇最小元素 - 它在本地選擇最佳元素。一切都喜歡貪婪,但事實並非如此。

你能解釋一下爲什麼我不這麼認爲嗎?關於這個問題的信息我還沒有在互聯網上找到。

沙发
0
0

設A是intgers的列表,使得:A = [5,4,3,6,1,2,7]

貪婪算法將尋找最有前途的方向,因此:

  1. 我們將比較:5比4,看到4確實是小於5,設置4作爲我們的最低
  2. 比較4比3,設置3作爲我們的最低
  3. 現在我們比較3-6,在這裏是一個棘手的部分:雖然在正常的選擇排序(蠻力),我們將繼續考慮剩下的數字,在a中貪婪的方法,我們將3作爲最低限度,不會考慮剩餘的數字,因此「本地最佳」。

所以使用這種方法的排序列表將導致排序作爲這樣的列表: [3,4,5,1,2,7]

+0

謝謝。所以貪婪應該停止,只要看起來目前的價值是最合適的?無論是否有更好的解決方案? –

+0

究竟:),而蠻力是從所有可能的解決方案中選擇最好的 –

板凳
0
1

貪婪和蠻力描述算法的不同性狀。

貪婪意味着,在每個步驟中的算法選擇一些選項,這是局部最好的。也就是說,它沒有前瞻性。

蠻力意味着該算法以一種簡單的方式查找選項,並考慮它們。例如。它可能會通過二進制搜索來搜索一個元素,並且它不再是蠻力。

所以算法可能既貪婪又蠻力。這些品質不是相互排斥的。

+0

所以,它是兩個,不是嗎?貪婪和蠻力 –

+0

@ S.Drumble1我會說是的,儘管這些定義並不是很正式。 –

地板
0
2

甲選擇排序確實可以被描述爲一個貪婪算法,在某種意義上說,它:

  • 嘗試選擇優化某一度量(「有序性」的輸出(其輸入的置換),其可以以各種方式進行測量,例如通過編號inversions),並且
  • 通過將任務分成更小的子問題(用於選擇排序,在輸出排列中找到第 - 個元素)並且選擇本地每個子問題的最優解。

碰巧,同樣的描述可以應用於大多數其他排序算法,以及—唯一真正的區別是子問題的選擇。例如:

  • 插入排序局部優化的?第一輸入元件的排列的有序性;
  • 氣泡排序優化相鄰元素對的排序;它需要多次遍歷列表以達到全局最優,但這仍然屬於貪婪算法的廣泛定義;
  • 合併排序優化了輸入序列的指數增長子序列的排序;
  • 快速排序遞歸地將其輸入劃分爲任意選擇的關鍵點任意一側的子序列,優化劃分以最大化每個階段的排序。

事實上,從我的頭頂,我想不出任何實際的排序算法,不會在這個意義上貪婪的。 (Bogosort不是,但很難稱爲實用)。此外,將這些排序算法作爲貪婪優化問題來配製,這樣在比較排序算法時會在實踐中模糊實際上非常重要的細節。

因此,我認爲將特徵選擇排序或任何其他排序算法視爲貪婪在技術上是有效的,但實際上是無用的,因爲這樣的分類不提供真正有用的信息。

0
votes
answers
27 views
+10

使用boost ::幾何多邊形布爾/與線段性質交叉

1

可能促進::幾何多邊形交集操作(交集,並集或差的布爾運算),同時保留用戶可能分配到的線段自定義屬性使用那個多邊形?使用boost ::幾何多邊形布爾/與線段性質交叉

例如,使用boost ::幾何,將下面的圖像中的兩個多邊形之間的布爾操作保存在方式原來多邊形的線段的顏色示出?

Image of polygon operations with edge properties as colour

正如人們可以定義定製point_xy對象送入布爾運算算法,這將是可能的屬性分配給各多邊形作爲輸入的一個頂點。問題是:輸出是否會以可預測的方式保留這些屬性?

如果加速幾何能做到這一點,將如何纔好呢?

注意:這裏有一個關於線串的相關問題:Find all linesegments=edges within a certain distance to a point in a graph, how to combine boost-graph with boost-geometry?,但據我所知,Boost幾何必須用點來定義多邊形,而不是布爾操作的線段。

沙发
0
1

不,保留這些特性尚無法在Boost.Geometry。

它計劃一次,所以也許它會在那裏的未來。在這種情況下,您將能夠提供一種策略來定義如何合併不同輸入的屬性。

但現在尚未實現。

+0

謝謝你。我可以想到在布爾操作之後將這些屬性添加到輸出多邊形的方法。不是很高效,因爲它必須找到每個輸出線段對應的原始線。 – TommyK

0
votes
answers
30 views
+10

如何在opencv中插入光滑圖像中的空洞?

0

我有相當光滑圖像以不同的光線條件:如何在opencv中插入光滑圖像中的空洞?

enter image description here ,我需要正確填寫孔。 編輯:我打算用雙線性插值。但如何正確在這種情況下使用它?

什麼interpolaion方法最適合,如何正確使用它。

+0

你的意思是你想填補黑色像素? –

+0

@ YvesDaoust,是的,所有黑色區域 – victor1234

沙发
0
1

我不會在這裏使用雙線性插值,因爲這些變化並不單調。

我寧願獨立使用三個RGB組件的全局二次模型。

對於擬合(最小二乘),可以取所有非黑色像素,儘管在一個或多或少密集網格上採樣應該足夠了。

請注意,在白色中也存在一些飽和現象,您應該忽略飽和像素(您將在重建後飽和值)。

+0

假設平板被點光源照亮,該模型將更準確地描述其亮度? – victor1234

+0

你可以推薦什麼樣的C++庫? – victor1234

+0

@ victor1234:無。如果我要這樣做,我會自己編程。 –

13
votes
answers
11 views
+10

Detecting endianness programmatically in a C++ program

Is there a programmatic way to detect whether or not you are on a big-endian or little-endian architecture? I need to be able to write code that will execute on an Intel or PPC system and use exactly the same code (i.e. no conditional compilation).

沙发
+30

untested, but in my mind, this should work? cause it'll be 0x01 on little endian, and 0x00 on big endian?

bool runtimeIsLittleEndian(void)
{
 volatile uint16_t i=1;
 return  ((uint8_t*)&i)[0]==0x01;//0x01=little, 0x00=big
}
板凳
+30

Declare:

My initial post is incorrectly declared as "compile time". It's not, it's even impossible in current C++ standard. The constexpr does NOT means the function always do compile-time computation. Thanks Richard Hodges for correction.

compile time, non-macro, C++11 constexpr solution:

union {
  uint16_t s;
  unsigned char c[2];
} constexpr static  d {1};

constexpr bool is_little_endian() {
  return d.c[0] == 1;
}

有沒有特別的原因你使用unsigned char而不是uint8_t? - 凱文2014年11月16日20:46

0運行時開銷...我喜歡它! - hanshenrik 2015年9月11日在1:05

我猜,這會檢測構建機器的endiannes,而不是目標? - hutorny 2015年10月23日12:07

在C ++中不是這個UB嗎? - rr- 2016年2月29日21:44

這在constexpr上下文中是不合法的。您無法訪問尚未直接初始化的聯合成員。沒有預處理器魔法,沒有辦法在編譯時合法地檢測字節順序。 - 理查德霍奇斯於2016年4月15日0:24

地板
+20

You can also do this via the preprocessor using something like boost header file which can be found boost endian

4楼
+20

If you don't want conditional compilation you can just write endian independent code. Here is an example (taken from Rob Pike):

Reading an integer stored in little-endian on disk, in an endian independent manner:

i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);

The same code, trying to take into account the machine endianness:

i = *((int*)data);
#ifdef BIG_ENDIAN
/* swap the bytes */
i = ((i&0xFF)<<24) | (((i>>8)&0xFF)<<16) | (((i>>16)&0xFF)<<8) | (((i>>24)&0xFF)<<0);
#endif
5楼
+10
int i=1;
char *c=(char*)&i;
bool littleendian=c;
6楼
+10

How about this?

#include <cstdio>

int main()
{
    unsigned int n = 1;
    char *p = 0;

    p = (char*)&n;
    if (*p == 1)
        std::printf("Little Endian
");
    else 
        if (*(p + sizeof(int) - 1) == 1)
            std::printf("Big Endian
");
        else
            std::printf("What the crap?
");
    return 0;
}
7楼
+10

Unless the endian header is GCC-only, it provides macros you can use.

#include "endian.h"
...
if (__BYTE_ORDER == __LITTLE_ENDIAN) { ... }
else if (__BYTE_ORDER == __BIG_ENDIAN) { ... }
else { throw std::runtime_error("Sorry, this version does not support PDP Endian!");
...

這些__BYTE_ORDER __,__ ORDERLE_ENDIAN__和__ORDER_BIG_ENDIAN__不是嗎? - Xeverous 3月25日'18在21:38

8楼
0

See Endianness - C-Level Code illustration.

// assuming target architecture is 32-bit = 4-Bytes
enum ENDIANESS{ LITTLEENDIAN , BIGENDIAN , UNHANDLE };


ENDIANESS CheckArchEndianalityV1( void )
{
    int Endian = 0x00000001; // assuming target architecture is 32-bit    

    // as Endian = 0x00000001 so MSB (Most Significant Byte) = 0x00 and LSB (Least     Significant Byte) = 0x01
    // casting down to a single byte value LSB discarding higher bytes    

    return (*(char *) &Endian == 0x01) ? LITTLEENDIAN : BIGENDIAN;
} 
9楼
0

Here's another C version. It defines a macro called wicked_cast() for inline type punning via C99 union literals and the non-standard __typeof__ operator.

#include <limits.h>

#if UCHAR_MAX == UINT_MAX
#error endianness irrelevant as sizeof(int) == 1
#endif

#define wicked_cast(TYPE, VALUE) 
    (((union { __typeof__(VALUE) src; TYPE dest; }){ .src = VALUE }).dest)

_Bool is_little_endian(void)
{
    return wicked_cast(unsigned char, 1u);
}

If integers are single-byte values, endianness makes no sense and a compile-time error will be generated.

10楼
0

The way C compilers (at least everyone I know of) work the endianness has to be decided at compile time. Even for biendian processors (like ARM och MIPS) you have to choose endianness at compile time. Further more the endianness is defined in all common file formats for executables (such as ELF). Although it is possible to craft a binary blob of biandian code (for some ARM server exploit maybe?) it probably has to be done in assembly.

11楼
0

while there is no quick and standard way to determine it, this will output it:

#include <stdio.h> 
int main()  
{ 
   unsigned int i = 1; 
   char *c = (char*)&i; 
   if (*c)     
       printf("Little endian"); 
   else
       printf("Big endian"); 
   getchar(); 
   return 0; 
} 
12楼
0

Do not use a union!

C++ does not permit type punning via unions!
Reading from a union field that was not the last field written to is undefined behaviour!
Many compilers support doing so as an extensions, but the language makes no guarantee.

See this answer for more details:

https://stackoverflow.com/a/11996970


There are only two valid answers that are guaranteed to be portable.

The first answer, if you have access to a system that supports C++20,
is to use std::endian from the <type_traits> header.

(At the time of writing, C++20 has not yet been released, but unless something happens to affect std::endian's inclusion, this shall be the preferred way to test the endianness at compile time from C++20 onwards.)

C++20 Onwards

constexpr bool is_little_endian = (std::endian::native == std::endian::little);

Prior to C++20, the only valid answer is to store an integer and then inspect its first byte through type punning.
Unlike the use of unions, this is expressly allowed by C++'s type system.

It's also important to remember that for optimum portability static_cast should be used,
because reinterpret_cast is implementation defined.

If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined: ... a char or unsigned char type.

C++11 Onwards

enum class endianness
{
    little = 0,
    big = 1,
};

inline endianness get_system_endianness()
{
    const int value { 0x01 };
    const void * address = static_cast<const void *>(&value);
    const unsigned char * least_significant_address = static_cast<const unsigned char *>(address);
    return (*least_significant_address == 0x01) ? endianness::little : endianness::big;
}

C++11 Onwards (without enum)

inline bool is_system_little_endian()
{
    const int value { 0x01 };
    const void * address = static_cast<const void *>(&value);
    const unsigned char * least_significant_address = static_cast<const unsigned char *>(address);
    return (*least_significant_address == 0x01);
}

C++98/C++03

inline bool is_system_little_endian()
{
    const int value = 0x01;
    const void * address = static_cast<const void *>(&value);
    const unsigned char * least_significant_address = static_cast<const unsigned char *>(address);
    return (*least_significant_address == 0x01);
}
13楼
-10

I was going through the textbook:Computer System: a programmer's perspective, and there is a problem to determine which endian is this by C program.

I used the feature of the pointer to do that as following:

#include <stdio.h>

int main(void){
    int i=1;
    unsigned char* ii = &i;

    printf("This computer is %s endian.
", ((ii[0]==1) ? "little" : "big"));
    return 0;
}

As the int takes up 4 bytes, and char takes up only 1 bytes. We could use a char pointer to point to the int with value 1. Thus if the computer is little endian, the char that char pointer points to is with value 1, otherwise, its value should be 0.

這將通過使用int32t得到改善。 - shuttle87 2014年11月11日16:53

^如果你想挑剔,這裡最好的是int16_fast_t。和@Ageimedes520的當前代碼將不適用於其中int本身就是int8;)(儘管可能首先違反c標準) - hanshenrik 2015年9月11日在1:11

14楼
-10

As pointed out by Coriiander, most (if not all) of those codes here will be optimized away at compilation time, so the generated binaries won't check "endianness" at run time.

It has been observed that a given executable shouldn't run in two different byte orders, but I have no idea if that is always the case, and it seems like a hack to me checking at compilation time. So I coded this function:

#include <stdint.h>

int* _BE = 0;

int is_big_endian() {
    if (_BE == 0) {
        uint16_t* teste = (uint16_t*)malloc(4);
        *teste = (*teste & 0x01FE) | 0x0100;
        uint8_t teste2 = ((uint8_t*) teste)[0];
        free(teste);
        _BE = (int*)malloc(sizeof(int));
        *_BE = (0x01 == teste2);
    }
    return *_BE;
}

MinGW wasn't able to optimize this code, even though it does optimize the other codes here away. I believe that is because I leave the "random" value that was alocated on the smaller byte memory as it was (at least 7 of its bits), so the compiler can't know what that random value is and it doesn't optimize the function away.

I've also coded the function so that the check is only performed once, and the return value is stored for next tests.

為什麼要分配4個字節來處理2字節值?為什麼用0x7FE掩蓋不確定的值?為什麼要使用malloc()?這很浪費。_BE是一個(雖然很小)內存洩漏和等待發生的競爭條件,動態緩存結果的好處並不值得。我會做更像這樣的事情:static const uint16_t teste = 1; int is_little_endian(){return(0x01 ==((uint8_t *)&teste)[0]); } int is_big_endian(){return(0x01 ==((uint8_t *)&teste)[1]); 簡單有效,在運行時執行的工作少得多。 - Remy Lebeau,18年5月3日0:08

這太糟糕了...... - YSC於18年11月27日14:32

@RemyLebeau,我的答案的重點是產生一個未經編譯器優化的代碼。當然,你的代碼更簡單,但啟用優化後,它將在編譯後成為一個常量布爾值。正如我在回答中所說,我實際上並不知道是否有某種方式來編譯C代碼的方式是在兩個字節順序上運行相同的可執行文件,我也很想知道我是否可以在運行時進行檢查儘管優化正在進行中。 - Tex Killer 5月14日3:22

@TexKiller然後為什麼不簡單地禁用代碼的優化?使用volatile或#pragma等 - Remy Lebeau 5月14日4:23

@RemyLebeau,我當時並不知道那些關鍵字,我只是把它作為一個小挑戰,以防止我知道的編譯器優化。 - Tex Killer 5月29日13:27