检查特定字符是否在字符串中

时间:2017-07-11 19:19:45

标签: python string counting

我需要查找并计算字符串中可以找到多少个字符。我把字符分成了chars1 [a:m]和chars2 [n:z],并且有两个计数器。

输出应为0/14,但它是0/1。我认为它只检查是否包含一个且只有一个项目,然后退出循环。是这样的吗?

这是代码。

string_1 = "aaabbbbhaijjjm"

def error_printer(s):
    chars1 = "abcdefghijklm"
    chars2 = "nopqrstuvwxyz"
    counter1 = 0
    counter2 = 0

    if ((c in s) for c in chars1):
        counter1 += 1
    elif ((c in s) for c in chars2):
        counter2 += 1
    print(str(counter2) + "/" + str(counter1))

error_printer(string_1)

6 个答案:

答案 0 :(得分:7)

chars1

中出现的chars2 / s中的字符数

这是有道理的,因为你if条件增加。由于循环中的if 不是,因此您可以将其递增一次。

现在我们可以展开for循环。这将解决问题的一部分,生成0/6

for c in chars1:
    if c in s:
        counter1 += 1
for c in chars2:
    if c in s:
        counter2 += 1

然而,这仍然不会非常有效:它需要 O(n)最坏的情况来检查字符是否在字符串中。您可以首先使用字符串中的字符构造set,然后执行查找(通常情况下通常为 O(1)

def error_printer(s):
    sset = set(s)
    chars1 = "abcdefghijklm"
    chars2 = "nopqrstuvwxyz"
    counter1 = 0
    counter2 = 0
    for c in chars1:
        if c in sset:
            counter1 += 1
    for c in chars2:
        if c in sset:
            counter2 += 1
    print(str(counter2) + "/" + str(counter1))

现在我们已经提高了效率,但它仍然不是很优雅:它需要大量的代码,而且还必须检查代码以了解它的作用。我们可以使用sum(..)构造来计算满足某个约束的元素数量,如:

def error_printer(s):
    sset = set(s)
    chars1 = "abcdefghijklm"
    chars2 = "nopqrstuvwxyz"
    counter1 = sum(c in sset for c in chars1)
    counter2 = sum(c in sset for c in chars2)
    print(str(counter2) + "/" + str(counter1))

这会产生0/6,因为[A-M]范围内的s范围内有六个字符,而[N-Z]范围内的s范围内有0个字符。

s / char1

中出现的char2中的字符数

根据问题正文,您希望计算s中出现在两个不同范围内的字符数

另一个相关问题是计算char1 / char2中出现的字符数。在这种情况下,我们只需交换循环

def error_printer(s):
    chars1 = set("abcdefghijklm")
    chars2 = set("nopqrstuvwxyz")
    counter1 = sum(c in chars1 for c in s)
    counter2 = sum(c in chars2 for c in s)
    print(str(counter2) + "/" + str(counter1))

这会产生0/14,因为s范围内有14个字符出现在[A-M]范围内(如果'a's中出现两次,那么我们会计算两次),s中没有任何字符出现在[N-Z]范围内。

使用范围检查

由于我们使用范围,我们可以使用比较而不是元素检查,并使其运行两次比较检查,例如:

def error_printer(s):
    counter1 = sum('a' <= c <= 'm' for c in s)
    counter2 = sum('n' <= c <= 'z' for c in s)
    print(str(counter2) + "/" + str(counter1))

答案 1 :(得分:6)

尝试使用if条件递增,在s上使用单个循环。

public class MainActivity extends AppCompatActivity {

    private FragmentManager manger;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        ArrayList<Chat> chatList = new ArrayList<>();
        chatList.add(new Chat("send post card", " ", R.drawable.sentpostcard));
        chatList.add(new Chat("send greeting card", "happy holiday", R.drawable.greetingcard));
        chatList.add(new Chat("special designs", "choose a card", R.drawable.special));


        ChatAdapter adapter = new ChatAdapter(chatList);
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.chatList);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(adapter);

    }



    // 1
    public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder>{

        // 7
        private ArrayList<Chat> chats;

        // 8
        public ChatAdapter(ArrayList<Chat> chats) {
            this.chats = chats;
        }

        // 10
        @Override
        public ChatViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = getLayoutInflater();
            View v = inflater.inflate(R.layout.chat_list_item, parent, false); // false == do not attach to root
            return new ChatViewHolder(v);
        }

        // 11
        @Override
        public void onBindViewHolder(ChatViewHolder holder, int position) {
            holder.bind( chats.get(position) );
        }

        // 9
        @Override
        public int getItemCount() {
            return chats.size();
        }

        // 2
        public class ChatViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

            //4
            private TextView textName, textChat;
            private ImageView imageChat;

            //we need to remember a chat for each view holder and we bind the chat object using the bind function
            //this will be useful later in the onClick Listener
            private Chat c;

            // view is the layout view ==> it contains all of the view in the layout file
            // 3
            public ChatViewHolder(View itemView) {
                super(itemView);
                // 5
                textName = (TextView) itemView.findViewById(R.id.textName);
                textChat = (TextView) itemView.findViewById(R.id.textChat);
                imageChat = (ImageView) itemView.findViewById(R.id.imageChat);



                // 12
                itemView.setOnClickListener(this);
            }

            // 6
            public void bind(Chat chat){
                c = chat;
                textName.setText(chat.getName());
                textChat.setText(chat.getText());
                imageChat.setImageResource(chat.getImage());
            }

            @Override
            public void onClick(View v) {

                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new FragA()).commit();


            }

            }
        }
    }

答案 2 :(得分:4)

for循环的替代方法:

string_1 = "aaabbbbhaijjjm"

def error_printer(s):
    chars1 = "abcdefghijklm"
    chars2 = "nopqrstuvwxyz"

    counter1 = sum(s.count(c) for c in chars1)
    counter2 = sum(s.count(c) for c in chars2)

    print(str(counter2) + "/" + str(counter1))

error_printer(string_1)

如果您计算"a""b""c" ...在字符串输入中显示的次数,那么您可以将其总结。

它仍然效率低下,但利用string.countsum函数,使其更容易阅读和理解正在发生的事情。

答案 3 :(得分:2)

两个计数器的s单个for循环:

string_1 = "aaabbbbhaijjjm"

def error_printer(s):
    chars1 = "abcdefghijklm"
    chars2 = "nopqrstuvwxyz"
    counter1 = 0
    counter2 = 0
    for c in s:
        if c in chars1:
            counter1 += 1
        if c in chars2:
            counter2 += 1
    print(str(counter2) + "/" + str(counter1))

error_printer(string_1)

答案 4 :(得分:2)

您可以将collections.Countersum结合使用:

from collections import Counter

def error_printer(s):
    cnts = Counter(s)
    chars1 = "abcdefghijklm"
    chars2 = "nopqrstuvwxyz"
    print(sum(cnts[c] for c in chars2), '/', sum(cnts[c] for c in chars1))

>>> error_printer("aaabbbbhaijjjm")
0 / 14

答案 5 :(得分:1)

正如已经建议的那样,for循环是可行的方法。您使用生成器表达式作为if语句的布尔值,该语句只运行一次。第一个表达式被评估True,但这不会使它多次运行包含的代码。但是,由于第一个if确实运行了,elif甚至从未评估其条件。这就是你想要循环的原因,但你不应该遍历char1和char2,你想循环遍历s:

for c in s:
    if c in char1:
        counter1 += 1
    if c in char2:
        counter2 += 1
print(str(counter2) + "/" + str(counter1))

这指出了一些更加流畅的方法,首先使用c in charX作为迭代器:

for c in s:
    counter1 += c in char1
    counter2 += c in char2

现在这已经变得不那么清楚,但我们可以通过添加第二个for循环来使它更清晰:

char = [‘abcdefghijklm’,’nopqrstuvwxyz’]
counter = [0,0]
for c in s:
    for i in [0,1]:
        counter[i] += c in char[i]

这可能有点推动它,但我希望它能帮助你看到如何在python中重新排列这些东西!

(根据以下评论进行编辑)